Il 0% ha trovato utile questo documento (0 voti)
27 visualizzazioni81 pagine

Appunti Informatica Di Base

Caricato da

arizeta03
Copyright
© © All Rights Reserved
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd
Il 0% ha trovato utile questo documento (0 voti)
27 visualizzazioni81 pagine

Appunti Informatica Di Base

Caricato da

arizeta03
Copyright
© © All Rights Reserved
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd

INFORMATICA

DI BASE
20/03

Computer:
Definizione (oggi): macchina per l'elaborazione di dati rappresentati da caratteri
alfanumerici variamente codificati, che vengono sottoposti a procedimenti aritmetici e
logici, memorizzati in archivi e resi reperibili e trasmissibili
Definizione (XVII secolo): qualcuno che esegue calcoli matematici
Definizione (accezione più generica): qualsiasi agente (ovvero, entità in grado di
agire se istruita appropriatamente, come una persona o una macchina) che sia in
grado di fare calcoli e produrre una risposta (detta output) a partire da qualche
informazione iniziale (detta input)

Il termine computer (calcolatore, in italiano) è in uso, oggi, per indicare una


“macchina per l'elaborazione di dati rappresentati da caratteri alfanumerici
variamente codificati, che vengono sottoposti a procedimenti aritmetici e logici,
memorizzati in archivi e resi reperibili e trasmissibili”. Tuttavia, la definizione originale
dello stesso termine, in uso dal diciassettesimo secolo, è leggermente differente,
visto che si riferisce a qualcuno che “esegue calcoli matematici”. In questo capitolo,
quando useremo il termine “computer”, considereremo sempre la sua accezione più
generica, ovvero: qualsiasi agente (ovvero, quell’entità in grado di agire se istruita
appropriatamente, come una persona o una macchina) che è in grado di fare calcoli
e produrre una risposta (detta output) a partire da qualche informazione iniziale
(detta input).
Computer umani, ovvero gruppi di persone che hanno eseguito lunghi calcoli per
determinati esperimenti, sono stati impiegati molte volte nel passato. Per esempio, in
astronomia, computer umani sono stati impiegati per calcolare le coordinate
astronomiche di oggetti extraterrestri – come i calcoli effettuati da Alexis Claude
Clairaut e colleghi per comprendere i vari passaggi della cometa di Halley. Come
ulteriore esempio, computer umani sono stati usati anche da Napoleone Bonaparte
quanto questo ha imposto la creazione di tabelle matematiche per convertire i valori
descritti con il vecchio sistema di misura imperiale verso il nuovo sistema metrico
(tutt’ora in uso).
Nel 1822, Charles Babbage, capendo la complessità di eseguire tutti questi calcoli a
mano evitando l’introduzione di errori, iniziò lo sviluppo di un nuova, incredibile,
macchina, chiamata Macchina Differenziale. L’idea era quella di avere a disposizione
una macchina che potesse gestire operazioni simili a quelle effettuate dai computer
umani, ma in modo che fossero eseguite automaticamente, velocemente, e senza
errori. Babbage fu in grado di costruire solo un prototipo parziale della macchina e,
dopo l’entusiasmo iniziale, fu demoralizzato dalla limitata flessibilità che offriva.
Infatti, la Macchina DIfferenziale non era programmabile e, di conseguenza, era in
grado di utilizzare solo un numero limitato di operazioni sull’input ricevuto –
specificato, fisicamente, cambiando specifiche configurazioni della macchina.
In modo da sopperire a queste limitazioni, nel 1837, Babbage iniziò a progettare una
nuova macchina, la Macchina Analitica, mostrata in Figura 2. Seppur nessun
prototipo di questa macchina sia stato effettivamente costruito da Babbage, in linea
di principio avrebbe dovuto permettere la creazione di qualunque calcolo
procedurale, rendendola il primo computer meccanico e general-purpose della
storia. Contrariamente al suo predecessore, la Macchina Analitica era in grado di
ricevere in input istruzioni e dati mediante l’uso di schede perforate, senza obbligare
l'utilizzatore, quindi, a compiere manipolazioni fisiche della macchina stessa per farla
funzionare.
C’è voluto più di un secolo per vedere sviluppate in una macchina fisica le idee
presentate nella Macchina Analitica. Infatti, l’evoluzione della tecnologia
computazionale ha avuto una brusca accelerata soltanto a seguito della Seconda
Guerra Mondiale. In quei tempi, molti calcolatori furono costruiti per ragioni militari,
come, ad esempio, la Bomba (1940), sviluppata da Alan Turing, che è stata il
principale strumento che ha permesso a un gruppo di persone, rinchiuse nella base
militare segreta britannica di Bletchley Park, di decifrare (grazie anche al lavoro
pregresso fatto da crittologi polacchi come Marian Rejewski) le comunicazioni
tedesche che erano state cifrate dalla macchina Enigma.
Mentre la Bomba era una macchina estremamente efficace ed efficiente, era altresì
parzialmente basata su componenti prettamente meccanici, e permetteva lo
svolgimento di una sola operazione, anche se estremamente cruciale da un punto di
vista squisitamente storico. Il primo computer interamente digitale, come pensato da
Babbage con la sua Macchina Analitica, è stato sviluppato negli Stati Uniti d’America
soltanto qualche anno dopo, nel 1946: l’Electronic Numerical Integrator and
Computer (ENIAC), mostrato in Figura 4, che era completamente programmabile
attraverso l’uso di cavi e interruttori. Questa invenzione è stata una delle più cruciali
pietre miliari della storia dei computer elettronici, rappresentando una sorta di “punto
fisso” nel tempo da cui tutti i moderni computer sono poi stati creati.
Macchina che fa dei calcoli in base ad un input che viene processato per la
restituzione di un output; è programmabile, elabora dati dopo averli codificati e
sottoposti a procedimenti logico-aritmetici. Già a partire dal medioevo era nata l’idea
di una macchina per effettuare calcoli → XVII secolo concetto di computer come
macchina per calcoli matematici.
Computer può essere sia una persona che una macchina, qualsiasi entità in grado di
agire e di essere istruita per fare dei calcoli date delle informazioni come input e di
produrre una risposta (output).
Computer umani nel ‘700 impiegati per:
● calcolare coordinate di oggetti extraterrestri
● creazione tabelle di conversione verso il nuovo sistema metrico
→ Problema: calcoli lunghi, errori facili
→Soluzione: Babbage (1822) sviluppa la Macchina Differenziale (solo un prototipo
parziale)
Ad oggi è impensabile che siano attuati da persone ma solo da computer per un
fattore di efficienza, precisione e velocità del processo.
Charles Babbage crea macchina in grado di sostituire l’uomo in determinati calcoli
→macchina differenziale →1822 costruzione di un prototipo che poteva effettuare
solo determinati calcoli (coordinate di oggetti extraterrestri) e non computazioni
generiche.

La Macchina Differenziale non era programmabile e, di conseguenza, era in grado di


utilizzare solo un numero limitato di operazioni sull’input ricevuto
Babbage (1837) progetta una la Macchina Analitica (nessun prototipo, solo disegni
del progetto):
● programmabile tramite schede perforate
● primo computer general purpose, può rispondere a qualsiasi problema se
istruita; solo progetto e non prototipo
Electronic Numerical Integrator and Computer (ENIAC, 1946): il primo computer
interamente digitale, sviluppato negli Stati Uniti d’America
Completamente programmabile attraverso l’uso di cavi e interruttori
Punto fisso nel tempo da cui tutti i moderni computer sono poi stati creati
1946 ENIAC costruì il primo computer interamente digitale e moderno →
produce info e le traduce in un sistema binario → è programmabile attraverso
collegamento di spinotti, cavi e interruttori che permettevano la sua
programmazione;

La Bomba di Turing, uno dei padri fondatori dell’intelligenza artificiale, macchina


per decifrare i messaggi del nemico nazista da parte degli Alleati →tecnica di
crittografia per comprendere codici nazisti applicando teorie di crittologi polacchi.
La ​Bomba (1940), sviluppata da Alan Turing​, è stata il principale strumento che ha
permesso a un gruppo di persone, rinchiuse nella base militare segreta britannica di
​Bletchley Park​, di decifrare (grazie anche al lavoro pregresso fatto da crittologi
polacchi come ​Marian Rejewski​) le comunicazioni tedesche che erano state cifrate
dalla ​macchina Enigma​.

Programmare o istruire?
Istruire una persona → simile alla programmazione, linguaggio naturale sviluppati
dall’uomo attraverso le ripetizioni nel tempo (vs linguaggio formale in cui parole
hanno sempre semantica ben definita e non ambigua e che è comprensibile alla
macchina) che trasmette istruzioni per risolvere un problema; due termini in qualche
misura simili ed equivalenti.

Pensiero computazionale
Area di ricerca e approccio per sviluppare sistemi che sappiano risolvere problemi
tramite processo di informazioni → problemi di processamento di informazioni.
Caratteristica per la risoluzione di problemi con approccio computazionale, il
processo mentale utilizzato è di astrazione → attenzione posta su determinati
aspetti specifici del problema per risolverlo e trascuramento di dettagli poco utili.
Caratteristica umana →problema è l’insegnamento alla macchina dell’astrazione.
Programmare un computer: OK se ci riferiamo a un computer elettronico, ma se ci
riferissimo a un computer umano? Possiamo programmare una persona?

Casomai diciamo che parliamo con una persona per istruirla sull’esecuzione di
specifiche azioni attraverso l’uso di un particolare linguaggio (in questo caso
naturale) che viene usato come canale di comunicazione
→Si dovrebbero usare gli stessi verbi, ovvero parlare e istruire, anche quando ci si
riferisce ad un computer elettronico
→Scrivere un programma: comunicare ad un computer elettronico utilizzando un
linguaggio (in questo caso formale) che sia l’istruttore umano sia il computer stesso
possano comprendere
Astrazione esempio: persone in fila →in modo inconscio l’uomo cattura le info
interessanti estraendole da tutte le info presenti → poca esperienza per apprendere
tali processi che vengono usati sempre anche inconsciamente.

Pensiero computazionale:
Spesso diciamo di programmare un computer – dove la parola “computer”, in questo
caso, si riferisce a un computer elettronico. Tuttavia, come anticipato nella
definizione che abbiamo fornito in questo capitolo, un computer può essere sia una
macchina sia un essere umano. Tuttavia, il verbo programmare non si presta
particolarmente bene ad essere usato con computer umani – visto che non
possiamo letteralmente programmare una persona (anche se qualche
pseudoscienza, come la programmazione neuro-linguistica, sostiene di poterlo fare).
Casomai diciamo che parliamo con una persona per istruirla sull’esecuzione di
specifiche azioni attraverso l’uso di un particolare linguaggio (in questo caso
naturale) che viene usato come canale di comunicazione. Di conseguenza, in questo
contesto, si dovrebbero usare gli stessi verbi, ovvero parlare e istruire, anche
quando ci si riferisce ad un computer elettronico perché, di fatto, è quello che
succede. In pratica, scrivere un programma è esattamente questo: comunicare ad
un computer elettronico utilizzando un linguaggio (in questo caso formale) che sia
l’istruttore umano sia il computer stesso possano comprendere.
Una volta d’accordo su quale linguaggio usare per la comunicazione tra l’istruttore e
il computer (a prescindere dal fatto che questo sia un umano o una macchina),
dovremmo iniziare a pensare una sequenza di possibili istruzioni da comunicare che,
se seguite sistematicamente, possano restituire un risultato atteso per risolvere un
certo problema. In modo da raggiungere questo obiettivo, solitamente (e
inconsapevolmente) proviamo a ricercare possibili soluzioni per il problema in
questione confrontandolo con possibili situazioni che si sono già presentate in
passato – e che, plausibilmente, abbiamo già risolto. L’idea è quella di trovare un
pattern (schema ricorrente) che fornisca una possibile soluzione a un insieme di
situazioni che, a livello astratto, sono del tutto omogenee, in modo da poter riusare la
stessa strategia per raggiungere il nostro obiettivo, se questa è stata soddisfacente
nel passato.
Considerando le situazioni e contesti appena riportati, possiamo definire il pensiero
computazionale come un approccio per risolvere problemi, sviluppare sistemi e
capire il comportamento umano che riprende i concetti fondamentali della
computazione [Wing, 2008] – dove con la parola computazione si intende calcolo. Il
pensiero computazionale definisce i processi mentali che coinvolgiamo quando
formuliamo un certo problema ed esprimiamo le relative soluzioni usando un
linguaggio che un computer (sia esso umano o macchina) può comprendere e,
conseguentemente, eseguire.
Jeannette Wing fornisce una definizione aggiuntiva, per chiarire ancor meglio cosa si
intenda per pensiero computazionale :“Il pensiero computazionale è un tipo di
pensiero analitico. Condivide, con il pensiero matematico, il modo in cui possiamo
approcciare un problema per trovarne la soluzione. Condivide, con il pensiero
ingegneristico, il modo in cui possiamo affrontare la progettazione e la valutazione di
grandi sistemi complessi che operano all’interno dei limiti del mondo reale. Infine,
condivide, con il pensiero scientifico, il modo in cui possiamo trattare la
comprensione della calcolabilità, l’intelligenza, la mente e il comportamento umano.”

La nozione principale dietro al pensiero computazionale è l’astrazione, ovvero


l’abilità di esercitare pensiero astratto e di esibire abilità di astrazione – che
comporta il processo di rimozione dei dettagli trascurabili di una situazione in modo
da semplificarla, per così focalizzare l’attenzione sulle sue caratteristiche principali .
Come già anticipato nell’esempio descritto in Figura 5, l’abilità di astrarre situazioni e
nozioni è cruciale per automatizzare l’esecuzione di determinate operazioni
attraverso l’uso di un computer che è responsabile dell’interpretazione di queste
astrazioni.
→Approccio per risolvere problemi, sviluppare sistemi e capire il comportamento
umano che riprende i concetti fondamentali della computazione (= calcolo).
Definisce i processi mentali che coinvolgiamo quando formuliamo un certo problema
ed esprimiamo le relative soluzioni usando un linguaggio che un computer (sia esso
umano o macchina) può comprendere e, conseguentemente, eseguire.
Astrazione: processo di rimozione dei dettagli trascurabili di una situazione in modo
da semplificarla, per così focalizzare l’attenzione sulle sue caratteristiche principali.
Usiamo le astrazioni in modo intenzionale o inconscio nella vita quotidiana.

Obiettivi del pensiero computazionale →dare forma alle info apprese in modo
inconscio con l’astrazione per la risoluzione di un problema →modalità di
espressione di esse tramite linguaggio comprensibile ad oggetti e persone.
Definizione generica: area di studi che cerca di istruire le persone a pensare come
se fossero computer scientist, cercare di strutturare i modi con cui risolviamo
problemi ed esprimere tale procedura con linguaggi interpretabili anche dalle
macchine →programmazione computer ma anche problemi quotidiani.
Dare nuovamente forma alle astrazioni che abbiamo già immagazzinato in passato
come conseguenza della nostra esperienza personale – e che, spesso, riutilizziamo
inconsciamente
Essere nuovamente e interamente coscienti di queste astrazioni significa doverle
ridefinire usando un linguaggio appropriato per renderle comprensibili a un computer
Obiettivo principale (dell’insegnamento) del pensiero computazionale: permettere
alle persone di pensare come se fossero computer scientist, anche quando bisogna
affrontare attività del quotidiano. Uno degli obiettivi del pensiero computazionale è
quello di dare nuovamente forma alle astrazioni che abbiamo già immagazzinato in
passato come conseguenza della nostra esperienza personale – e che, spesso,
riusiamo inconsciamente. Quindi, per essere nuovamente e interamente coscienti di
queste astrazioni, dobbiamo ridefinirle usando un linguaggio appropriato per
renderle comprensibili a un computer. Questo richiede a volte una notevole capacità
di introspezione e di riflessione sulle caratteristiche più importanti di un oggetto, di un
discorso o di una situazione, non troppo diversamente da ciò che avviene nel
pensiero filosofico o semiotico, ma sempre garantendo precisione e adeguatezza
alla risoluzione di problemi e alla rappresentazione del loro contenuto. Questo
indipendentemente dal fatto che vogliamo risolvere il problema di come elaborare un
testo digitale, di come organizzare i dati relativi a un’indagine archeologica, o di
come trovare il modo migliore per raccomandare un prodotto o un servizio.

A livello generale, l’obiettivo principale (dell’insegnamento) del pensiero


computazionale è quello di permettere alle persone di pensare come se fossero
computer scientist, anche quando bisogna affrontare attività del quotidiano. In futuro,
il pensiero computazionale sarà parte integrante dell’educazione primaria delle
persone , come la matematica e la fisica, e plasmerà il modo in cui le persone
pensano e imparano e di conseguenza, vivono.
In modo indiretto, questo sta già avvenendo attraverso la trasformazione dei sistemi
di produzione e comunicazione: il Web e i social media, gli “orchestratori di reti”
(come AirBnB e Uber), etc. Categorie fondamentali dell’esistenza umana: spazio,
tempo, identità, immagine pubblica, collettività, pianificazione, relazioni
interpersonali, etc. sono tutte influenzate dalla trasformazione socio-tecnica in
maniera più veloce e profonda di quanto sia avvenuto negli ultimi secoli.

Organizzare le informazioni:
Organizzazione delle informazioni in strutture-dati →modalità di organizzazione
generica, standard e valide per qualsiasi tipo di info da gestire →nomi diversi a
seconda di ciò di cui si ha bisogno e hanno caratteristiche differenti.
Fa parte del processo di astrazione il descrivere l’informazione presente in una certa
situazione secondo un’organizzazione generica e riutilizzabile in più contesti
Si usano quelle che comunemente sono chiamate strutture dati: una sorta di
contenitore dove possiamo posizionare alcune informazioni, e che fornisce dei
metodi specifici per aggiungere e richiedere pezzi di questa informazione
Esempi: liste, code, pile, insiemi, dizionari, alberi e grafi
Definizione struttura dati: contenitore che memorizza info in una determinata
maniera e in cui queste si inseriscono e si prelevano.
Uno dei processi di base dell’attività di astrazione è quella di descrivere
l’informazione presente in una certa situazione secondo un’organizzazione generica
e riutilizzabile in più contesti. Per fare ciò, si usano quelle che comunemente sono
chiamate strutture dati. Le strutture dati sono i modi in cui possiamo organizzare
l’informazione e i dati da essere processati (input) e restituiti (output) da un
computer, in modo da potervi accedere in modo efficiente ed efficace a livello
computazionale. In pratica, una struttura dati è una sorta di contenitore dove
possiamo posizionare alcune informazioni, e che fornisce dei metodi specifici per
aggiungere e richiedere pezzi di questa informazione.
Tra le più semplici strutture dati abbiamo: le liste, le code, le pile, gli insiemi, i
dizionari, gli alberi e i grafi. Tutte queste strutture verranno analizzate nelle
sottosezioni che seguono, fornendo esempi delle loro applicazioni in scenari
quotidiani.
Strutture più comuni a seguito di analisi → scegliere le strutture date più efficienti per
i programmatori a seconda dei dati che deve manipolare:
● lista → sequenza ordinata di elementi secondo ordine di inserimento e
che possono essere potenzialmente ripetuti; non ha dimensione prefissata
(vs altre strutture dati che hanno contenuto max di elementi); info inserita in
qualsiasi suo punto e accesso a qualsiasi info ovunque questa si trovi al
suo interno; strumento informatico flessibile → sequenza di parole o di
qualsiasi elemento; libri in una libreria. Sequenza di elementi ordinati e
potenzialmente ripetibili che si possono contare, perché si può sapere quanti
elementi essa contiene in un dato momento.
Una lista è una sequenza di elementi ordinati e ripetibili che si possono
contare, perché si può sapere quanti elementi essa contiene in un dato
momento. I suoi elementi sono ordinati perché sono posizionati in uno
specifico ordine di precedenza tra loro, che è preservato anche quando
aggiungiamo e rimuoviamo determinati elementi. Inoltre, gli elementi in una
lista sono ripetibili, visto che possono comparire più di una volta in una lista –
ad esempio, se proviamo a creare una lista di caratteri della parola “pensiero”,
la lettera “e” comparirà due volte, una in seconda posizione, e un’altra in
sesta posizione.

● pila → sequenza ordinata di elementi secondo ordine di inserimento ma


che però al contrario della lista consente di aggiungere o rimuovere
elementi solo secondo alcune regole determinate dal LIFO →si può
accedere solo all’ultimo elemento inserito in cima alla pila; non c’è limite di
elementi con dimensione prefissata →aggiunta elementi fino all’infinito
(determinata in realtà dalla memoria del dispositivo); libri impilati; per
accedere ad elemento centrali, bisogna rimuoverli progressivamente dalla
cima della lista. Una specie di lista vista da un particolare punto di vista con
uno specifico insieme di operazioni che si possono effettuare sugli
elementi della pila; le operazioni di aggiunta e rimozione seguono una
strategia last in first out (LIFO).
Una pila è una specie di lista vista da un particolare punto di vista, ovvero dal
basso verso l’alto, e con uno specifico insieme di operazioni che si possono
effettuare sugli elementi della pila. Figura 8 mostra due esempi di pile in
oggetti di tutti i giorni. In particolare, abbiamo una pila di sedie (a sinistra) e
una pila di libri (a destra). La caratteristica principale degli elementi di questa
struttura riguarda le operazioni di aggiunta e rimozione, che seguono una
strategia last in first out strategy (LIFO) – ovvero, l’ultimo elemento che viene
inserito è il primo ad essere rimosso. Infatti, l’ultimo elemento inserito nella
struttura è posizionato in cima alla pila e, quindi, è anche il primo che verrà
rimosso se richiesto. Inoltre, se si vuole rimuovere un elemento in mezzo alla
pila, è prima necessario rimuovere tutti gli elementi che sono stati posizionati
dopo questo, dal più recente al più vecchio.

● coda → particolare tipo di lista (sequenza ordinata per la memorizzazione di


info secondo l’ordine di inserimento) in cui aggiunta e rimozione avvengono
secondo regola FIFO → primo elemento a cui si può accedere è il primo
inserito; tubo; Una specie di lista vista da un’altra prospettiva e con uno
specifico insieme di operazioni che possono essere effettuate sugli elementi
che contiene; le operazioni di aggiunta e rimozione seguono una strategia first
in first out (FIFO).
Una coda è una specie di lista vista da un’altra prospettiva, ovvero da sinistra
verso destra, e con uno specifico insieme di operazioni che possono essere
effettuate sugli elementi che contiene. Figura 9 mostra due differenti esempi
di code in situazioni del quotidiano: una coda di bambini (sinistra) e una linea
di attesa di taxi (destra). La caratteristica principale degli elementi di questa
struttura riguarda le operazioni di aggiunta e rimozione degli elementi, che
seguono una strategia first in first out strategy (FIFO) – ovvero, il primo
elemento che viene aggiunto è anche il primo che viene rimosso a seguito di
una richiesta. In pratica, il primo elemento inserito nella struttura è posizionato
nella parte libera più a sinistra della coda e, di conseguenza, è anche il primo
che verrà rimosso quando richiesto. In modo del tutto simile alle pile, anche
nelle code, se si vuole rimuovere un certo elemento in mezzo, è necessario
prima rimuovere tutti gli elementi che sono stati aggiunti prima di esso.

● insieme → collezione di elementi non ordinati e non ripetibili, distribuiti


secondo un ordine particolare; si possono contare; info non possono
essere ripetute; non c’è limite al numero di elementi inseribili; accesso alle
info dipende da vari fattori e da come viene implementato ma di solito le
librerie di programmazione richiedono di dare un ordine agli elementi
contenuti che poi bisogna scorrere→ classe di alunni
Un insieme è una collezione di elementi non ordinati e non ripetibili che si
possono contare. I suoi elementi non sono ordinati perché l’ordine di
inserimento di questi non prescrive nessuna relazione di cardinalità tra loro.
Inoltre, sono non ripetibili perché lo stesso valore non può essere incluso due
o più volte.

● dizionario (o mappa) → collezione non ordinata di elementi definiti da


coppie chiave-valore che si possono contare ma dove la chiave non è
ripetibile →vocabolario in cui ad ogni parola è associata descrizione dei
significati → esmpio: stato del mondo associato al valore della sua valuta in
euro. Un dizionario (o array associativo) è una collezione non ordinata di
elementi definiti da coppie chiave-valore che si possono contare, dove la
chiave non è ripetibile. I suoi elementi sono non ordinati perché l’ordine di
inserimento non prescrive nessuna relazione di cardinalità tra gli elementi, in
modo del tutto simile agli insiemi. Inoltre le chiavi di ogni coppia non sono
ripetibili perché la stessa chiave non può essere usata due o più volte nel
dizionario.

● albero → struttura dati in cui gli elementi hanno relazioni tra loro; insieme di
nodi collegati tra loro da una relazione gerarchica genitore-figlio → stesso
elemento può essere in relazione con più elementi ed essere al contempo
padre e figlio; solitamente ogni elemento ha un solo padre ma può avere più
figli; albero genealogico → Un albero è una struttura dati composta da un
insieme di nodi collegati tra loro da una relazione gerarchica genitore-figlio.

● grafo → insieme di nodi di una rete collegata da archi (che possono


essere anche orientati) →relazioni non seguono gerarchia ma sono
arbitrarie in cui gli elementi potrebbero avere lo stesso ruolo →usati per i
social network e le relazioni di amicizia in cui non ci sono ruoli gerarchici ma è
simmetrica tra due persone; molto utili e usati per rappresentare info
generiche per risolvere problemi complessi →navigatori per la struttura di
strade e percorsi. Due tipi di relazioni: non direzionali (relazione simmetrica
tra due elementi) o direzionali (rappresentare collegamenti ipertestuali
all’interno di una pagina web)
I grafi sono una delle principali strutture dati in informatica e, in generale, del
pensiero computazionale. Sono usati per descrivere, in termini astratti, molte
situazioni del mondo reale come tragitti tra città, relazioni tra persone nei
social network, l’organizzazione dei collegamenti ipertestuali tra pagine Web]
e le relazioni concettuali nelle basi di dati o nei knowledge graph usati per
esempio da Google , Amazon e Facebook per i loro servizi.

→Usati per descrivere, in termini astratti, molte situazioni del mondo reale: tragitti tra
città, relazioni tra persone nei social network, l’organizzazione dei collegamenti
ipertestuali tra pagine Web e le relazioni concettuali nelle basi di dati
Algoritmi e computabilità

● Algoritmo → procedura, sequenza di istruzioni che un agente deve


compiere per risolvere un dato problema →input e output →ingredienti di
una ricetta e risultato finale a seguito della loro manipolazione; pezzi di un
mobile, procedimento per montaggio e risultato finito; albero decisionale

Gli algoritmi accompagnano sistematicamente le nostre attività della vita quotidiana.


esempi di procedure passo passo che dobbiamo seguire, rispettivamente, per
preparare salatini e per assemblare una specifica lampada. Mentre l’obiettivo dei
due esempi è estremamente diverso, in quanto nel primo è una ricetta e nel secondo
è un insieme di istruzioni per assemblare un utensile, essi sono descritti nei termini
della stessa nozione astratta: istruzione per produrre qualcosa partendo da un
qualche materiale iniziale a disposizione – che, di fatto, rispecchia pienamente la
definizione di algoritmo.
La parola algoritmo è una combinazione della parola latina algorismus (che, a sua
volta, è la latinizzazione del nome Al-Khwarizmi, che era un grande matematico
persiano dell’ottavo secolo) e della parola greca arithmos, che significa numero. A
livello generale, possiamo definire un algoritmo come l’astrazione di una procedura
passo passo che prende qualcosa come input e produce un certo output . Ogni
algoritmo è scritto in un linguaggio specifico in modo che le istruzioni che definisce
possano essere comunicate e comprese da un computer (sia esso umano o
macchina) in modo da ottenere qualcosa come conseguenza dell’elaborazione di
qualche materiale di input. Un programmatore è una persona che crea algoritmi e li
specifica in programmi usando uno specifico linguaggio comprensibile dal computer
– ove, in questo caso, il termine computer si riferisce ai computer elettronici.
Tuttavia, se ci si astrae dalla nozione di programma, un programmatore è chiunque
sia in grado di creare algoritmi che possono essere interpretati da un qualunque
computer (sia esso umano o macchina).
Situazioni accomunate da manipolazione di fattori per generare un risultato
→descrivono una serie di situazioni per passare da una situazione iniziale (input) ad
una finale (output) →descritti in linguaggi differenti a seconda dei diversi contesti di
fruizione.
Definizione di input e output in un computer devono essere scritti in un linguaggio a
lui comprensibile.

Definizione →un algoritmo è:


Un’astrazione di una procedura passo passo che prende qualcosa come input e
produce un certo output, scritta in un linguaggio specifico in modo che le istruzioni
che definisce possano essere comunicate e comprese da un computer in modo da
ottenere qualcosa come conseguenza dell’elaborazione di qualche materiale di input
Un programmatore è una persona che crea algoritmi e li specifica in programmi
usando uno specifico linguaggio comprensibile sia da lui che la scrive sia dal
computer (elettronico) che deve leggere l’istruzione e interpretarla. Se il computer è
umano si parla di istruttore.

Ada Lovelace, matematica inglese che partecipò (1833) ad una festa organizzata da
Charles Babbage per presentare la Macchina Differenziale, e ne fu così colpita che
iniziò una corrispondenza epistolare con lui che durò 27 anni
Fu la traduttrice in inglese del primissimo articolo sulla Macchina Analitica
scritto da Luigi Federico Menabrea, e che lei stessa arricchì con un grande numero
di annotazioni personali e riflessioni
Fu la prima programmatrice della storia →tra le varie annotazioni che Ada aggiunse
al testo, c’era anche una descrizione di come usare la Macchina Analitica per
calcolare i numeri di Bernoulli, sequenza numerica (come serie di Fibonacci)
→algoritmo che prendeva in input dei numeri e generava altri numeri.

Ada Lovelace era la figlia del poeta Lord Byron. Matematica di formazione, è
diventata famosa per il suo lavoro sulla Macchina Analitica di Babbage. La madre,
Anne Isabella Milbanke, In contrasto con le abitudini del padre, che mal sopportava il
suo interesse per la cultura scientifica, aveva invece da sempre supportato
l’interesse che Ada aveva nella logica e nella matematica. Uno degli obiettivi della
madre, infatti, era quello di evitare che la figlia incorresse nella stessa sregolatezza
emozionale ed esistenziale che aveva caratterizzato la vita del padre. Tuttavia, in
qualche modo la creatività insita nella famiglia venne poi manifestata in modi
assolutamente imprevedibili.

Nel 1833, Ada partecipò ad una festa organizzata da Charles Babbage per
presentare la Macchina Differenziale. Fu talmente colpita dall’invenzione di Babbage
che iniziò una corrispondenza epistolare con lui che durò 27 anni. Ada fu la
traduttrice in inglese del primissimo articolo sulla Macchina Analitica, scritto da Luigi
Federico Menabrea, e che lei stessa arricchì con un grande numero di annotazioni
personali e riflessioni. Tra queste, c’era anche una descrizione di come usare la
Macchina Analitica per calcolare i numeri di Bernoulli . Tecnicamente, questo fu il
primo programma – nonché il primo algoritmo – per un computer digitale mai scritto,
e fu creato da Ada senza avere neppure a disposizione la macchina reale, visto che
la Macchina Analitica era soltanto una macchina teorica che Babbage non costruì
mai.
Questo è riconosciuto come il primo programma della storia dei computer, creato
senza avere a disposizione la macchina reale, visto che la Macchina Analitica era
soltanto teorica, che di fatto fa di Ada la prima programmatrice della storia
“[La Macchina Analitica] potrebbe operare su altre cose oltre ai numeri, se si
trovassero oggetti le cui relazioni fondamentali possano essere espresse da quelle
della scienza astratta delle operazioni”
→Immaginò quali potessero essere operazioni eseguite le operazioni su quel tipo di
macchina →Scienza astratta delle operazioni = informatica
Che linguaggio usare per definire un algoritmo?

Non esiste un linguaggio standard per descrivere un algoritmo in modo che possa
essere immediatamente comprensibile da un qualunque computer.
Di solito si usa uno pseudocodice, ovvero un linguaggio informale (simile al
linguaggio naturale prendendone delle frasi) per descrivere i passi principali di un
algoritmo ad un umano, anche se non è direttamente eseguibile da un computer
elettronico →ambiguità del linguaggio informale,le istruzioni non sono
comprensibili alle macchine che non sono in grado di comprenderla; anche se i suoi
costrutti sono strettamente connessi con quelli tipicamente definiti nei linguaggi di
programmazione.
Descrizione utile per poterla trasformare da un programmatore in un linguaggio di
programmazione e formale che possa essere eseguibile dalla macchina.
Un esempio di pseudocodice: i diagrammi di flusso – li abbiamo informalmente
introdotti prima quando abbiamo visto la “Mappa per le discussioni”.

Oggetti grafici di un diagramma di flusso


Non esiste un linguaggio standard per descrivere un algoritmo in modo che possa
essere immediatamente comprensibile da un qualunque computer. Tuttavia, spesso
gli informatici si basano su uno pseudocodice quando vogliono descrivere un
particolare algoritmo. Uno pseudocodice è un linguaggio informale che può essere
facilmente interpretato da un qualunque computer, anche se è solitamente usato per
comunicare i passi principali di un algoritmo ad un umano. Mentre un algoritmo
descritto mediante l’uso di pseudocodice non è eseguibile da un computer
elettronico, i suoi costrutti sono strettamente connessi con quelli tipicamente definiti
nei linguaggi di programmazione. In particolare, ogni algoritmo può essere espresso
in pseudocodice e, in principio, questo può essere a sua volta tradotto, abbastanza
facilmente, in diversi linguaggi di programmazione. La vera differenza è che, di
solito, alcuni passaggi dello pseudocodice possono essere semplificati usando delle
espressioni in linguaggio naturale, mentre, in un linguaggio di programmazione,
bisogna necessariamente definire in modo chiaro tutti i passaggi.
In questo capitolo, useremo una particolare alternativa grafica al comune
pseudocodice che è facilmente comprensibile dagli umani: i diagrammi di flusso. Un
diagramma di flusso è uno specifico tipo di diagramma che può essere usato per
scrivere algoritmi, e che si basa su un limitato insieme di oggetti grafici, introdotti in
Tabella 1.
Descrive flusso di istruzioni che l’algoritmo deve seguire–linguaggio informale che
serve per comunicare un algoritmo ad un altro umano che può prendere tale
descrizione e trasformarla in linguaggio formale utile per istruire un computer → 5
oggetti grafici
Oggetto grafico Nome Definizione

Linea di flusso La freccia è usata per definire l’ordine in cui le operazioni sono
eseguite. Il flusso indicato dalla freccia inizia in un terminale di
partenza e finisce in un terminale di fine (vedi l’oggetto
successivo).

Terminale Viene usato per indicare l’inizio e la fine di un algoritmo (si


trova l’etichetta di inizio o di fine). Contiene un testo (solitamente
o “inizio” o “fine”, in italiano) in modo da disambiguare qual è il
ruolo del particolare oggetto terminale nel contesto dell’algoritmo.

Processo Simbolo che viene usato per esprimere un’istruzione testuale in


linguaggio naturale che è eseguita e che può cambiare lo stato
corrente di qualche variabile usata nell’algoritmo. Il testo che
contiene descrive l’istruzione da eseguire.

Decisionale Permette di esprimere operazioni condizionali, dove una


condizione è verificata e, a seconda del valore di alcune variabili
usate nell’algoritmo, l’esecuzione continua in un particolare
ramo del flusso invece che in un altro. Di solito, questa
operazione crea due possibili rami: uno seguito se la
condizione è vera, e un altro che viene seguito quando la
condizione è falsa.

Input / Output Permette di specificare un possibile input o output che viene


usato o restituito dall’algoritmo solitamente all’inizio o alla
fine della sua esecuzione →cosa riceve in input e cosa deve
generare in output

Gli algoritmi non sono sempre una sequenza lineare di istruzione → in alcuni punti
vanno prese delle decisioni rispetto a compiere un’azione o un’altra →decisionali

In questo capitolo svilupperemo il nostro primo algoritmo, che può essere descritto
informalmente come segue: prendere in input tre stringhe, ovvero due parole e un
riferimento bibliografico di un articolo pubblicato, e restituire 2 se entrambe le parole
sono contenute nel riferimento bibliografico, 1 se solo una delle parole è contenuta
nel riferimento bibliografico, o 0 altrimenti.

PRIMO ALGORITMO INCOMPLETO:


Prendi in input tre stringhe, (stringa→sequenza di caratteri →parola, titolo di un
articolo) ovvero due parole e un riferimento bibliografico di un articolo pubblicato,
e l’output deve essere un numero, e restituisci:

● 2 se entrambe le parole sono contenute nel riferimento bibliografico


● 1 se solo una delle parole è contenuta nel riferimento bibliografico
● 0 altrimenti
Esempio riferimento bibliografico:
Shannon, C. E. (1948). A Mathematical Theory of Communication. Bell System
Technical Journal, 27(3), 379–423. doi:10.1002/j.1538-7305.1948.tb01338.x

Esempio parole: “Theory” e “Journal” →risultato 2


“Conference” e “Bells” → 0 →attenzione al singolare e plurale
“Logical” e “System” → 1

Versione parziale dell’algoritmo


Mediante i diagrammi di flusso, un qualunque algoritmo è definito usando due
oggetti terminali, che identificano l’inizio e la fine dell’algoritmo. Il terminale di inizio
ha una freccia che parte da esso e va verso l’istruzione successiva (la prima
dell’algoritmo), mentre il terminale di fine può essere raggiunto da differenti punti
dell’algoritmo, e quindi è collegato da almeno una freccia.
La prima versione incompleta dell’algoritmo, mostrata di seguito, semplifica un poco
le istruzioni in linguaggio naturale precedentemente introdotte, in modo da mostrare
come possiamo usare alcuni iniziale oggetti per creare un algoritmo, senza
aggiungere ulteriore complessità, almeno per il momento. In particolare, la versione
semplificata prende in input solo due stringhe, una parola e un riferimento
bibliografico, e restituisce 1 se la parola è contenuta nel riferimento bibliografico, 0
altrimenti. Questa versione parziale è mostrata nel diagramma di flusso in Figura 3.
Prende in input due stringhe, una parola e un riferimento bibliografico, e restituisce:

● 1 se la parola è contenuta nel riferimento bibliografico


● 0 altrimenti

Nel parallelogramma si descrive il significato dell’operazione → domanda espressa


nel rombo →due possibili opzioni a seguito di una decisione
Questa versione parziale usa già molti degli oggetti grafici propri ai diagrammi di
flusso. In particolare, oltre ai terminali di inizio e fine, abbiamo usato tre oggetti di
input / output per acquisire i valori specificati come input e per restituire 0 o 1
dipendentemente da questo input. La decisione su quale output restituire è stata
codificata grazie all’oggetto decisionale dei diagrammi di flusso, in cui l’input è
analizzato e, a seconda della situazione, uno specifico ramo del flusso dell’algoritmo
viene percorso.

Cosa abbiamo usato?

❖ Diverse linee di flusso


❖ Due oggetti terminali di inizio e fine
❖ Tre oggetti di input / output per acquisire i valori specificati come input e per
restituire 0 o 1 dipendentemente da questo input
❖ Un oggetto decisionale dei diagrammi di flusso

Valori booleani →risposta solo true o false

Versione finale
Mentre nella sezione precedente è stata introdotta una prima implementazione della
versione parziale dell’algoritmo, l’implementazione dell’algoritmo completo attraverso
lo sviluppo di un diagramma di flusso è mostrata in Figura 4. In questo caso, sono
stati utilizzati tutti gli oggetti grafici introdotti in Tabella 1. Tuttavia, è importante
sottolineare come il diagramma di flusso presentato è soltanto un possibile modo per
implementare l’algoritmo originale. Infatti, è possibile creare anche un diagramma di
flusso diverso che, però, risolve il problema descritto dall’algoritmo in linguaggio
naturale correttamente. Nel diagramma in Figura 4, viene utilizzato il primo oggetto
di processo in cui viene inizializzato a 0, associandolo implicitamente a una variabile
(ovvero, “result value” in figura), il risultato che verrà restituito alla fine
dell’esecuzione dell’algoritmo. Questo risultato è quello che l’algoritmo deve ritornare
se entrambe le parole in input non sono contenute nel riferimento bibliografico
specificato. Questo oggetto di processo è seguito da due oggetti decisionali messi in
sequenza, che controllano le due condizioni – ovvero se la prima parola è contenuta
nel riferimento bibliografico, e se la seconda parola è contenuta nello stesso
riferimento – e, nel caso queste siano vere, eseguono un incremento di 1 al risultato
finale da restituire, mediante l’uso di altri oggetti di processo. Alla fine, qualunque sia
il valore che è stato associato al risultato finale viene restituito da un unico oggetto di
output, che conclude l’esecuzione dell’algoritmo.

Prendi in input due parole e un riferimento bibliografico e restituisci 2 se entrambe le


parole sono contenute nel riferimento bibliografico 1 se solo una delle parole è
contenuta nel riferimento bibliografico,0 altrimenti
Definire intenzione di un algoritmo → esistono tante descrizioni per uno stesso
algoritmo; variabile →casella in cui si scrivono valori →inizializza il valore finale a 0
è la nostra variabile, mantenimento di info parziali che sono necessarie per il
procedimento.
Prima parola input è contenuta nel riferimento bibliografico?
-sì→ somma 1 al valore finale (si cancella lo zero di prima)
-no→la seconda parola è contenuta? →due risposte →si (sommo 1 al valore finale);
no →restituiremo il valore finale (quindi 0)

Variabile qui chiamata “valore finale” mantiene il conto delle parole contenute nel
riferimento bibliografico →la inizializza a zero perché ancora non ha analizzato
parole.

Tre domande chiave del pensiero computazionale

● Possiamo usare gli algoritmi per computare(calcolare, generare informazioni)


qualsiasi cosa vogliamo?
● Esiste un limite a quello che possiamo computare?
● È possibile definire un problema computazionale – ovvero un problema che
può essere risolto algoritmicamente da un computer – che non può essere
risolto da nessun algoritmo?

Analisi della complessità di un algoritmo nel:


-tempo
-spazio →memoria necessaria per arrivare ad una soluzione
Una delle domande tradizionali che le persone, che si avvicinano al pensiero
computazionale e agli algoritmo, di solito si pongono è: possiamo usare gli algoritmi
per computare qualsiasi cosa vogliamo? In altre parole: esiste un limite a quello che
possiamo computare? O ancora: è possibile definire un problema computazionale –
ovvero un problema che può essere risolto algoritmicamente da un computer – che
non può essere risolto da nessun algoritmo?

Nel caso dell’informatica, ma anche di tutte le scienze matematiche, uno degli


approcci più usati per dimostrare che qualcosa non esiste è quello di costruire una
situazione in apparenza plausibile che, poi, si rivela paradossale e
auto-contraddittoria – in cui, per esempio, l’esistenza di un algoritmo contraddice se
stessa. Questo approccio dimostrativo porta il nome di reductio ad absurdum
(dimostrazione per assurdo). L’argomentazione che ne sta alla base è quella di
stabilire che una situazione è contraddittoria cercando di derivare un’assurdità dalla
sua negazione, in modo da dimostrare che una tesi deve essere accettata perché la
sua negazione non può essere difesa [Rescher, 2017] e, alla fine, genera un
paradosso.
I paradossi sono stati usati molte volte in logica nel passato. Mentre, da un punto di
vista, possono essere considerate storie divertenti da usare per insegnare, da un
altro punto di vista sono strumenti potenti che mostrano i limiti di particolari aspetti
formali di una situazione. Per esempio, uno dei più famosi paradossi in matematica è
il paradosso di Russell, scoperto da Bertrand Russel nel 1901. È stata una delle più
grandi scoperte dell’inizio del ventesimo secolo, poiché ha provato che l’allora teoria
degli insiemi proposta da Georg Cantor, e usata come base fondazionale per tutto il
lavoro che Gottlob Frege stava facendo per definire le leggi di base dell’aritmetica,
portava ad una contraddizione. Di conseguenza, il paradosso di Russell invalidava
l’intera teoria degli insiemi e il lavoro fatto da Frege stesso – che era in stampa
quando Russell gli comunicò la sua scoperta. Una variazione del paradosso può
essere formulata come segue.

Digressione: il paradosso
I paradossi possono essere considerati:
● delle storie divertenti da usare per insegnare
● strumenti potenti che mostrano i limiti di particolari aspetti formali di una
situazione
Paradosso del bibliotecario: Nella Biblioteca di Babele, tutte le persone sono di una
delle due seguenti tipologie. La prima tipologia di persone, le indipendenti
(no-needed in Figura 5), sono quelle che, quando devono cercare un libro per loro
stesse, lo fanno da sole senza chiedere aiuto a nessuno. L’altro tipo di persone,
ovvero le bisognose (help-needed), sono quelle che non sono in grado di cercare un
libro da sole, e che necessitano dell’aiuto del bibliotecario per trovarlo. Ora, una
delle persone nella biblioteca è il bibliotecario, che cerca un libro per tutte e sole le
persone bisognose, ovvero quelle che non sono in grado di cercare quel libro da
sole. Considerando questa situazione, la domanda è: chi cerca i libri al bibliotecario?
Risoluzione: Se il bibliotecario fosse indipendente, ovvero si cercasse i libri da solo,
verrebbe meno la premessa che lo vuole cercare i libri solo per le persone
bisognose – quindi, se fosse indipendente allora sarebbe bisognoso. Se invece non
fosse in grado di cercarsi i libri da solo, e quindi fosse bisognoso, allora dovrebbe
farsi aiutare dal bibliotecario, che però è lui stesso – quindi, se fosse bisognoso
allora sarebbe indipendente.
Uno dei più importanti problemi studiati in informatica anni fa, che faceva parte dei
23 problemi aperti della matematica che David Hilbert propose nel 1900, è noto col
nome di problema della terminazione. Questo problema riguardava il capire se fosse
possibile sviluppare un algoritmo che fosse in grado di rispondere se un altro
algoritmo, specificato come input, terminasse la sua esecuzione o no. L’algoritmo
proposto in Figura 4 è un esempio di uno di quelli che termina, ma è possibile anche
sviluppare un algoritmo che non termina mai, ad esempio come mostrato in quello
definito in Figura 6. Avere un modo per scoprire sistematicamente se un algoritmo
termina la sua esecuzione o no sarebbe di importanza cruciale, perché
permetterebbe immediatamente di identificare quegli algoritmi che non lavorano in
modo appropriato.

Definizione: data una situazione che descrive un particolare problema, qualunque


strada che si intraprende per trovare la soluzione del suddetto problema porta
ad una contraddizione.
Uno degli scienziati che di più a lavorato alla risoluzione di questo quesito è stato
Alan Mathison Turing (mostrato in Figura 7). Alan Turing è stato un informatico,
nonché padre dell’informatica teorica e dell’intelligenza artificiale, anche se i suoi
lavori hanno interessato diverse discipline tra cui la matematica (si vedano gli studi
per decodificare la macchina Enigma), la logica (con l’introduzione della macchina di
Turing [Turing, 1937]), la filosofia (si veda lo studio sulla relazione tra i calcolatori
elettronici e il concetto di intelligenza [Turing, 1950]) e la biologia (si veda lo studio
che identifica i processi spontanei di creazione di pattern in natura [Turing, 1952]).
Nel 1936, Turing sviluppò la sua macchina proprio per cercare di rispondere al
problema della terminazione di Hilbert. La macchina proposta da Turing era
prettamente teorica, nel senso che non l’aveva costruita fisicamente, anche se
recentemente molte persone hanno provato a costruire prototipi fisici dell’idea di
Turing, come quello mostrato in Figura 8.
La macchina, che è in grado di simulare l’esecuzione di qualunque algoritmo
realmente implementabile, è composta da un nastro di memoria infinito composto da
celle. Ogni cella può contenere un simbolo (o 0 o 1, dove 0 è usato come default per
inizializzare le celle di tutto il nastro) che può essere letto e scritto dalla testina della
macchina. Lo stato in cui la macchina si trova in un certo momento è altresì
annotato. Le operazioni che può fare la macchina in un certo stato sono definite in
una tabella (finita) di istruzioni, dove ogni istruzione dice cosa fare (scrivere un
nuovo simbolo, muovere la testina a sinistra o a destra, spostarsi in un nuovo stato)
in base allo stato in cui la macchina si trova e al simbolo presente nella cella sotto la
testina. Infine, sono forniti anche uno stato iniziale e zero o più stati finali, in modo da
sapere dove iniziare e finire il processo.
La macchina è stata usata da Turing per mostrare una soluzione per il problema
della terminazione. In questo capitolo presentiamo un’approssimazione alla
soluzione che Turing ha fornito, basata interamente sulla reductio ad absurdum, già
usata per risolvere il paradosso del bibliotecario, e sui diagrammi di flusso come
un’astrazione grafica di una specifica macchina di Turing.
Supponiamo sia possibile sviluppare l’algoritmo “termina?”, che prende in input un
certo algoritmo e restituisce “vero” nel caso in cui l’algoritmo specificato come input
termina, mentre restituisce “falso” in caso contrario. Ovviamente, questo è soltanto
un algoritmo ipotetico: stiamo supponendo che possiamo svilupparlo in qualche
modo, senza mostrare come farlo davvero.

Ora, usiamo l’algoritmo “termina?” per sviluppare un nuovo algoritmo, introdotto nel
diagramma di flusso in Figura 9. Questo nuovo algoritmo prende in input un
algoritmo e restituisce 0 se l’algoritmo in input non termina, mentre non termina in
caso contrario. Notate che siamo in grado di implementare davvero ogni passo di
questo nuovo algoritmo, siccome scoprire se l’algoritmo in input termina è restituito
dal nostro algoritmo (ipotetico) “termina?”, mentre la non terminazione è un processo
chiaramente implementabile, visto che ne abbiamo introdotto un esempio in Figura
6.

Ora la domanda è: cosa succede se cerchiamo di eseguire l’algoritmo descritto in


Figura 9 usando se stesso come input? Abbiamo due situazioni possibili:

-l’algoritmo “termina?” afferma che il nostro algoritmo in Figura 9 termina, e


conseguentemente (per come è definito) non termina l’esecuzione;
-l’algoritmo “termina?” afferma che il nostro algoritmo in Figura 9 non termina, e
conseguentemente (per come è definito) restituisce 0 e termina l’esecuzione.

Quindi, qualunque sia il comportamento del nostro algoritmo in Figura 9, la sua


esecuzione passando se stesso come input genera sempre una contraddizione.
L’unica spiegazione possibile, quindi, è che l’algoritmo ipotetico “termina?” che
usiamo per decidere se un algoritmo termina o meno non può essere sviluppato. Di
conseguenza, la risposta al problema della terminazione è che l’algoritmo che
verifica se un altro termina non può esistere.

Esempio: la biblioteca di Babele


-persone indipendenti →cercano libri da sole
-persone bisognose →del bibliotecario per prendere un libro
-bibliotecario →cerca libri per tutte e sole le persone bisognose
A quale delle due categorie appartiene il bibliotecario? Chi cerca i libri al
bibliotecario? E’ una persona bisognosa o indipendente?
Se è:
-bisognosa →è sé stesso che deve prendersi i libri → contraddice che le persone
bisognose hanno bisogno del bibliotecario per prenderseli e non può prenderli da
soli
-indipendente → è sé stesso che deve prendere i libri → viene meno il fatto che
aiuta solo le persone bisognose

Perchè i paradossi sono utili


Non è possibile definire un algoritmo per computare qualsiasi cosa →dimostrazione
per assurdo.
Uno degli approcci più usati per dimostrare che qualcosa non esiste è quello di
costruire una situazione in apparenza plausibile che, poi, si rivela paradossale e
auto-contraddittoria – in cui, per esempio, l’esistenza di un algoritmo contraddice se
stessa. Questo approccio dimostrativo porta il nome di reductio ad absurdum
(dimostrazione per assurdo): stabilire che una situazione è contraddittoria cercando
di derivare un’assurdità dalla sua negazione, in modo da dimostrare che una tesi
deve essere accettata perché la sua negazione non può essere difesa e, alla fine,
genera un paradosso.

I problemi aperti della matematica


23 problemi aperti della matematica proposti da David Hilbert 1900 e che includono
(indirettamente) il problema della terminazione: capire se fosse possibile
sviluppare un algoritmo che fosse in grado di rispondere se un altro algoritmo,
specificato come input, terminasse la sua esecuzione o no.

È possibile sviluppare un algoritmo che non termina mai la sua esecuzione?

Si genera un loop
infinito, algoritmo che non termina → non arriva mai ad un risultato →problema

Alan Turing
Alan Mathison Turing è stato un informatico, padre dell’informatica teorica e
dell’intelligenza artificiale → sviluppò la sua macchina teorica (1936) proprio per
cercare di rispondere al problema della terminazione di Hilbert.
Inventò una macchina è in grado di simulare l’esecuzione di qualunque algoritmo
realmente implementabile →fu esperimento mentale e non fisico; nastro infinito e
puntatore che permette di scrivere 0 e 1 nelle caselle →simulare qualsiasi algoritmo
e studiarne le caratteristiche

Approssimazione della soluzione di Turing


Premessa: supponiamo sia possibile sviluppare l’algoritmo “termina?”, che prende in
input un certo algoritmo e restituisce “vero” nel caso in cui l’algoritmo specificato
come input termina, mentre restituisce “falso” in caso contrario
NB: è soltanto un algoritmo ipotetico, stiamo supponendo che possiamo
svilupparlo in qualche modo, senza mostrare come farlo davvero
Usiamo questo algoritmo per crearne un altro
Nuovo algoritmo
Nuovo algoritmo: prendi in input un algoritmo e restituisci 0 se l’algoritmo in input
termina, mentre non terminare in caso contrario

E se usiamo il nuovo algoritmo come suo input?

Caso 1: se l’algoritmo “termina?” afferma che il nuovo algoritmo termina,


conseguentemente (per come è definito) il nuovo algoritmo non termina l’esecuzione
Contraddizione →l’algoritmo riesce a terminare

Caso 2: se l’algoritmo “termina?” afferma che il nuovo algoritmo non termina, e


conseguentemente (per come è definito) il nuovo algoritmo restituisce 0 e termina
l’esecuzione
Contraddizione →l’algoritmo non termina

→ La contraddizione è un paradosso: l’algoritmo che verifica se un altro


termina non può esistere

I limiti della computazione


Questo risultato ha avuto un effetto dirompente sulla percezione delle abilità
computazionali che un computer può avere.
La macchina di Turing e le relative analisi effettuate su di essa hanno imposto dei
limiti chiarissimi a quello che possiamo calcolare, e hanno permesso di
dimostrare che determinati problemi computazionali interessanti, come quello
della terminazione, non possono essere risolti da nessun approccio
algoritmico. Tutto questo è stato possibile solo grazie all’applicazione di un
pensiero computazionale esclusivamente astratto, considerando che la macchina di
Turing è solo uno strumento prettamente teorico
Questo risultato ha avuto un effetto dirompente sulla percezione delle abilità
computazionali che un computer può avere. In pratica, la macchina di Turing e le
relative analisi effettuate su di essa hanno imposto dei limiti chiarissimi a quello che
possiamo calcolare, e hanno permesso di dimostrare che determinati problemi
computazionali interessanti, come quello della terminazione, non possono essere
risolti da nessun approccio algoritmico.

Linguaggio “naturale”
● È linguaggio comune, come l’italiano, lingua dei segni
● Può essere scritto o orale
● Si è evoluto in maniera naturale all’interno di una comunità
● Vantaggio: molto espressivi, descrivono un gran numero di fatti/oggetti
● Svantaggi: alcune frasi sono intrinsecamente ambigue se non
accompagnate da un opportuno contesto, ad una frase si possono
solitamente associare più significati

Una linguaggio “naturale” è un linguaggio comune, come l’italiano, che può essere
scritto o orale, e che si è evoluto in maniera naturale all’interno di una comunità. Da
come li conosciamo, i linguaggi naturali hanno il vantaggio (e, contemporaneamente,
lo svantaggio) di essere così tanto espressivi che specifiche istruzioni comunicate
attraverso il loro uso possono sembrare ambigue.Consideriamo, per esempio, la
frase “la vecchia porta la sbarra”. Questa frase significa che c’è una vecchia porta
che blocca qualcuno o che c’è una signora anziana che trasporta una sbarra?
Tuttavia, spesso, noi riusciamo a disambiguare il significato di una frase mediante
l’uso di convenzioni sociali o analizzando il contesto in cui l’azione avviene, in modo
da restringere il possibile significato di un pezzo di informazione.
Mentre i linguaggi naturali non sono formali per definizione, molti studi in linguistica
cercano di fornirne una formalizzazione mediante l’uso di strumenti matematici
Interpretazione ambigua

La vecchia porta la sbarra 2 significati


I made her duck 5 significati

Il significato di una frase può essere disambiguato mediante l’uso di


convenzioni sociali o analizzando il contesto in cui l’azione avviene, in modo da
restringere il possibile significato di un pezzo di informazione.
L’uomo è in grado di disambiguare la frase da tono, intonazione e contesto rispetto
al linguaggio naturale. Le macchine non sono ancora in grado di disambiguare bene
perché non possono fare domande ad esempio.
Formalizzazione di un linguaggio
I linguaggi naturali non sono formali per definizione
Tuttavia molti studi in linguistica cercano di fornirne una formalizzazione mediante
l’uso di strumenti matematici per descriverlo in modo formale rispetto ad una
certa lingua e rispetto alla sua sintassi e semantica.
Una delle figure più importanti dietro alla formalizzazione del linguaggio naturale è
Noam Chomsky, uno dei più importanti accademici degli ultimi cento anni e uno dei
padri della linguistica moderna, insieme a Ferdinand de Saussure.
Chomsky è uno dei padri della linguistica moderna – le cui ipotesi di ricerca
principali sul linguaggio umano sono:
- la sua struttura sintattica di base è rappresentabile mediante una teoria
matematica
- tale struttura è determinata biologicamente in tutti gli umani e usata
anche inconsciamente; una caratteristica unica che si è evoluta nel tempo e
che è condivisa soltanto dagli umani e non da altri animali
Questa sua visione del linguaggio umano è molto dibattuta, ma ha avuto il merito di
fondare su basi rigorose la ricerca sulle relazioni tra competenza e produzione
linguistica, sulle dinamiche e le interazioni tra capacità “innate” e sviluppo cognitivo e
sociale delle abilità linguistiche. Ha anche permesso di chiarire in parte distinzioni
come sintassi vs. semantica, lessico vs. discorso, tra rappresentazione logica e
rappresentazioni mentali ecc.
Linguaggi e grammatiche formali
Tra la sua produzione accademica troviamo la classificazione delle grammatiche
formali in una gerarchia di crescente potere espressivo, che rappresenta uno dei suoi
più importanti contributi, considerando il suo impatto anche al di fuori della
linguistica tradizionale – per esempio nel dominio dell’informatica teorica e nei
linguaggi di programmazione, come vedremo in seguito.

→Una grammatica formale è uno strumento matematico usato per definire la


sintassi di un linguaggio (sia lingue naturali come l’italiano, sia linguaggi artificiali)
attraverso l’uso di un insieme finito di regole di produzione, che permettono di
costruire una qualunque frase valida in quello specifico linguaggio.

Un linguaggio formale possiamo pensarlo come un insieme di frasi


Una grammatica formale permette descrive come generare un linguaggio ed è
definita da 4 elementi:
● un insieme di regole di produzione che spiegano come le frasi sono
strutturate e come vengono generate → premessa ::= espressione; dove la
premessa e l’espressione possono contenere uno o più simboli delle seguenti
tipologie:
● simboli terminali ovvero mattoncini di base che formano le frasi del
linguaggio cioè le parole; (specificato tra virgolette in BNF), che identifica tutti
i simboli elementari del linguaggio in considerazione (come nomi, verbi, etc.);
● simboli non-terminali permettono di costruire la struttura delle frasi
→simbolo non terminale (specificato tra parentesi angolari in BNF), che
identifica tutti i simboli di una grammatica formale che possono essere
sostituiti da una combinazione di simboli terminali e non terminali.

● simbolo iniziale che indica da dove partire per generare le frasi

Grammatica formale
Un insieme di regole di produzione di forma premessa ::= espressione, dove la
premessa e l’espressione possono contenere uno o più:

● simboli terminali (specificati tra virgolette), che identificano tutti i simboli


elementari del linguaggio in considerazione (come nomi, verbi, etc.)
● simboli non terminali (specificati tra parentesi angolari), che identificano
tutti i simboli di una grammatica formale che possono essere sostituiti da una
combinazione di simboli terminali e non terminali. Il simbolo iniziale è quello
che indica qual è la prima regola che bisogna applicare per costruire la frase.

Esempio:
In linea di principio, l’applicazione di una regola di produzione riguarda la
sostituzione dei simboli nella premessa con quelli specificati nell’espressione
finché non si raggiunge una sequenza che include soltanto simboli terminali. Per
esempio, le regole di produzione <frase> ::= "Io" <verbo>, <verbo> ::= "scrivo" e
<verbo> ::= "leggo" permette la creazione di tutte le frasi di due parole che hanno il
pronome di prima persona singolare accompagnato da uno dei verbi possibili (ad
esempio “Io scrivo”). In più, ogni grammatica formale deve specificare un simbolo di
inizio, che deve essere non terminale.

<frase> ::= cioè sostituisci con il segmento "Io" <verbo> se trovo simbolo frase
posso sostituirlo con io e verbo
<verbo> ::= "scrivo" | "leggo" se trovo simbolo non terminale verbo lo posso
sostituire con scrivo o con leggo

Il simbolo non terminale <frase> è il simbolo iniziale.


Frasi che possiamo produrre da questa grammatica:
Io scrivo
Io leggo
Gerarchia di Chomsky
La gerarchia proposta da Chomsky mette a disposizione un modo per descrivere
formalmente le relazioni che possono esistere tra diverse grammatiche in termini
delle loro possibili strutture sintattiche che sono in grado di generare. In pratica,
queste tipologie sono caratterizzate dal tipo di simboli che possono essere usati
nella premessa e nell’espressione delle regole di produzione. Queste tipologie di
grammatica sono elencate di seguito, dalla meno espressiva alla più espressiva
[vengono usate le lettere dell’alfabeto greco per indicare una qualsivoglia possibile
combinazione di simboli terminali e non terminali, incluso il simbolo terminale vuoto,
solitamente rappresentato con ε]:
Chomsky ha proposto una gerarchia per descrivere formalmente le relazioni che
possono esistere tra diverse grammatiche in termini delle loro possibili strutture
sintattiche che sono in grado di generare.
Queste tipologie sono caratterizzate dal tipo di simboli che possono essere usati
nella premessa e nell’espressione delle regole di produzione (lettere greche usate
per indicare una combinazione di simboli terminali e/o non terminali):

● grammatiche regolari – <nt> ::= "t" | "t" <nt> – regole di produzione seguono
questo schema, si possono avere solo espressioni di questo tipo dato il
simbolo iniziale ; – forma delle regole di produzione:
○ <non-terminale> ::= "terminale"
○ <non-terminale> ::= "terminale" <non-terminale>
○ Esempio:
<frase> ::= "Io" <verbo>
<verbo> ::= "scrivo"
<verbo> ::= "leggo"

● grammatiche libere dal contesto – <nt> ::= γ qualsiasi sequenza di


simboli terminali e non terminali → – forma delle regole di produzione:
○ <non-terminale> ::= γ
○ Esempio:
<frase> ::= <pronome> <frase-verbale>
<pronome> ::= "Io"
<nome> ::= "libro"
<nome> ::= "documento"
<frase-verbale> ::= <verbo>
<frase-verbale> ::= <verbo> "un" <nome>
<verbo> ::= "scrivo"
<verbo> ::= "leggo"
● grammatiche dipendenti dal contesto – α <nt> β ::= α γ β simbolo non
terminale si trova in un contesto che viene mantenuto nell’espressione. –
forma delle regole di produzione:
○ α <non-terminale> β ::= α γ β
○ Esempio:
<frase> ::= <pronome-soggetto> <frase-verbale>
"Io" <pronome-oggetto> <verbo> ::= "Io" <pronome-oggetto> "amo"
"Io" <verbo> <nome> ::= "Io" "leggo" "un" <nome>
<frase-verbale> ::= <verbo> <nome>
<frase-verbale> ::= <pronome-oggetto> <verbo>
<pronome-soggetto> ::= "Io"
<pronome-oggetto> ::= "ti"
<pronome-oggetto> ::= "vi"
<nome> ::= "libro"
<nome> ::= "documento"
● grammatiche ricorsivamente enumerabili – α ::= β – regole di produzione
sono libere, si può avere una qualsiasi premessa genere una qualsiasi
espressione. una premessa può anche non generare alcun simbolo – forma
delle regole di produzione:
○ α ::= β (nessuna restrizione)
○ Esempio:
<frase> ::= <pronome-soggetto> <frase-verbale>
"Io" <pronome-oggetto> <verbo> ::= "Io" "ci" "vedo"
"Io" <verbo> <nome> ::= "Io" "leggo" "un" "libro"
<frase-verbale> ::= <verbo> <nome>
<frase-verbale> ::= <pronome-oggetto> <verbo>
<pronome-soggetto> ::= "Io"
<pronome-oggetto> ::= "mi"
<pronome-oggetto> ::= "ti"
<verbo> ::= "amo"
<verbo> ::= "odio"

Regole di produzione che garantiscono determinate caratteristiche–4 tipi di


grammatiche regolari e formali che permettono 4 tipi di produzione a seconda di
specifiche caratteristiche.

Queste grammatiche sono utili nei compilatori, cioè strumenti che prendono codice
di un software e verificano che rispetti regole di sintassi del linguaggio di
programmazione.
Semplice verificarlo per le grammatiche regolari ed è estremamente complicata per
quelle ricorsivamente enumerabili – difficoltà crescente.

Cosa sono i linguaggi di programmazione


C’è un particolare aspetto di ogni computer (sia esso umano o macchina) che non è
stato ancora affrontato direttamente, ovvero: quale meccanismo possiamo usare per
chiedere a un computer di eseguire una particolare attività? La modalità per
affrontare questo problema è estremamente connessa con il particolare canale
comunicativo che vogliamo adottare. Se consideriamo un computer umano,
possiamo usare un linguaggio naturale (ad esempio l’italiano) o i diagrammi di flusso
per istruirlo sui passi algoritmici che deve compiere. Invece, per comunicare
efficacemente con un computer elettronico si usano i linguaggi di programmazione.

Un linguaggio di programmazione è un linguaggio formale che obbliga l’uso di


specifiche regole sintattiche sviluppate in modo tale da evitare possibili
istruzioni ambigue – linguaggio deve essere semplice da interpretare per un
computer.
Solitamente l’espressività del linguaggio è ridotta ma tutte le “frasi” componibili
trasmettono un solo possibile significato – non è possibile esprimere qualsiasi
comando o istruzione quindi si ha un’espressività molto ridotta.
I linguaggi di programmazione sono solitamente basati su grammatiche libere dal
contesto, è più facile la verifica della grammatica, e possono distinguersi per un
basso interagiscono la cpu che effettua i calcoli nel computer o elevato livello
di astrazione istruzioni ad alto livello che permettono di astrarre da problemi di
memoria del computer e di cpu. Si distinguono per quanto più si avvicinano alle
istruzioni che il calcolatore deve eseguire rispetto al linguaggio propriamente in uso
da un elaboratore elettronico per eseguire le operazioni.
Utile avere linguaggi a basso livello che non devono gestire le astrazioni che sono
poco efficienti quando le istruzioni sono eseguite.
Un linguaggio di programmazione è un linguaggio formale che obbliga l’uso di
specifiche regole sintattiche sviluppate in modo tale da evitare possibili istruzioni
ambigue – solitamente restringendo l’espressività del linguaggio – cosicché tutte le
“frasi” componibili possano trasmettere un solo possibile significato. I linguaggi di
programmazione sono solitamente basati su grammatiche libere dal contesto, in
conformità con la classificazione Chomskiana fornita nella sezione precedente – e
possono distinguersi per un basso o elevato livello di astrazione dal linguaggio
propriamente in uso da un elaboratore elettronico per eseguire le operazioni. In
particolare, possiamo raggruppare i linguaggi di programmazione in tre macro
insiemi
Linguaggio macchina
Un insieme di istruzioni che possono essere eseguite direttamente dalla CPU
(central processing unit, o processore) di un computer elettronico. CPU è in grado
di compiere poche operazioni come somme o alcuni tipi di moltiplicazioni. Numeri
manipolati sono espressi secondo un codice binario e non decimale – ogni
operazione va ridotta a somma o moltiplicazione di numeri binari affinché la cpu
possa operare su questa sequenza in modo molto rapido.

Basato sul codice binario – una sequenza di 0 e 1 – rivisitato da Leibniz alla fine
del diciassettesimo secolo.

11010011101110110011011011111110010110110111000011110100110100111000
111100001

i n f o r m a t i c
a

Linguaggi di programmazione a basso livello


sono linguaggi che forniscono un livello di astrazione sopra il linguaggio macchina, e
che permettono di scrivere programmi in modo che siano un pochino più intellegibili
dagli umani. Il più famoso linguaggio di questo tipo è l’Assembly. Anche se introduce
simboli più comprensibili, di solito una linea di codice in Assembly rappresenta una
specifica istruzione in linguaggio macchina.
Forniscono un livello di astrazione sopra il linguaggio macchina che
permettono di avere aiuti per programmare – a livello più alto l’interprete del
linguaggio di programmazione traduce in sistema binario l’informazione. Esistono più
livelli di astrazione.
Permettono di scrivere programmi in modo che siano più intellegibili dagli umani
Il più famoso linguaggio di questo tipo è l’Assembly – non istruisce cpu con codici
binari ma astrae poco rispetto al basso livello, anche se introduce simboli più
comprensibili, di solito una linea di codice in Assembly rappresenta una specifica
istruzione in linguaggio macchina, spesso invece che gestire info di memoria
a seconda del bit permette di dare un nome alle caselle-celle di memoria
chiamate registri della cpu, per aiutarci quando si definisce un programma
senza dover gestire direttamente il codice binario manipolato dalla cpu.

fib:
mov edx, [esp+8]
cmp edx, 0
ja @f
mov eax, 0
ret

@@:
cmp edx, 2
ja @f
mov eax, 1
ret

@@:
push ebx
mov ebx, 1
mov ecx, 1

Linguaggi di programmazione ad alto livello


Caratterizzati da un forte livello di astrazione dal linguaggio macchina –
esempio: Python, permette di definire istruzioni usando parole chiave molto vicine al
linguaggio naturale – più semplice per un programmatore leggere e scrivere un
programma.
linguaggi caratterizzati da un forte livello di astrazione dal linguaggio macchina. In
particolare, possono usare parole proprie del linguaggio naturale per definire
costrutti specifici, così da essere di più facile comprensione per un umano. A livello
generale, più astrazione da un linguaggio di programmazione a basso livello è
fornita, più comprensibile è il linguaggio. Possono usare parole proprie del
linguaggio naturale per definire costrutti specifici, così da essere di più facile
comprensione per un umano. Interprete Python gestisce la grammatica. Più
astrazione da un linguaggio di programmazione a basso livello è fornita, più
comprensibile è il linguaggio

def fib(n):
if n <= 0:
return 0
elif n <= 2:
return 1
else:
a=1
b = 1 – assegnazione, interprete prende codice del programma e
istruisce cpu a seguire tali istruzioni, la cpu esegue computazione effettiva
while True:
c=a+b
if n <= 3:
return c
a=b
b=c
n=n-1

Sintassi semplice di Python vicina al linguaggio naturale – qui viene definita una
funzione fib che prende n come input e segue la procedura. Gestire astrazioni è
complicato per un interprete – istruzioni sono minori a basso livello –efficienza e
velocità.

I primi linguaggi
Grace Brewster Murray Hopper è tra i più grandi pionieri dei linguaggi di
programmazione. Il primo programmatore dell’ Harvard Mark I, un computer
elettromeccanico general-purpose, computer istruito secondo un programma per
eseguire una serie di istruzioni ed elaborare la soluzione. Fu usato durante la
seconda guerra mondiale. Hopper era fermamente convinta della necessità di
avere linguaggi di programmazione che fossero indipendenti dalle macchine
specifiche su cui erano utilizzati, che l’ha portata allo sviluppo del COBOL
(linguaggio ad alto livello) per avere un linguaggio unitario che valesse per tutte le
macchine – linguaggio ad alto livello vs basso livello dipendono dalla cpu della
macchina su cui vengono eseguite.

Evoluzione dei linguaggi di programmazione


Regole diverse che consentono caratteristiche diverse nel linguaggio – spesso
influenzato da altri linguaggi esistenti in uno sviluppo continuo.
Dopo la seconda guerra mondiale, sono stati creati diversi linguaggi di
programmazione, con caratteristiche specifiche a seconda dei principi di sviluppo e
dell’uso che se ne doveva fare – ad esempio, dipendentemente dai problemi
computazionali per cui venivano usati. Mentre tutti questi linguaggi, in principio,
permettono lo sviluppo di soluzioni per un qualsiasi problema computazionale, alcuni
di questi sono più appropriati per determinati domini rispetto ad altri. Per esempio, il
COBOL, come già anticipato, è stato sviluppato per la creazione di applicazioni
industriali, mentre il FORTRAN è stato sviluppato per gestire al meglio la
computazione di dati scientifici.

Linguaggi visuali
Quelli visti fino ad ora erano linguaggi testuali ma ne esistono anche di visuali –
diagramma di flusso siccome comprende linguaggio informale non possiamo
considerarlo come visuale a tutti gli effetti.
In modo da facilitare l’avvicinamento all’uso dei linguaggi di programmazione
tradizionali, negli ultimi anni sono stati sviluppati diversi linguaggi di programmazione
visuali che permettono lo sviluppo di piccoli programmi per risolvere problemi
computazionali specifici – concentrazione sulla risoluzione più che su come
scriverla.

Alcuni sono proposti sotto forma di gioco, e permettono l’introduzione dei costrutti
principali propri dei linguaggi di programmazione mediante l’utilizzo di oggetti
grafici

Un esempio
Nel 2017, Google ha messo a disposizione un doodle in cui si deve istruire un
coniglio in modo che riesca a mangiare tutte le carote posizionate su un determinato
percorso. Le azioni che si possono far compiere al coniglio riguardano attività di
movimento, ad esempio “vai avanti” o “gira a destra”, e devono essere disposte in
una specifica sequenza
Problema computazionale: mangiare tutte le carote presenti sul percorso e le
istruzioni da dare al coniglio sono relative ai suoi movimenti per raggiungere il suo
obiettivo.

Uso di blocchi al posto delle parole

Può essere descritto anche con un diagramma di flusso, un altro linguaggio


possibile.

Ciclo – costrutto ripetuto di una sequenza di istruzioni, consente di scrivere


programmi in modo più compatto. Per mantenere il conto si tiene una variabile, una
casella in cui si scrive il numero di iterazioni a cui si è arrivati

Costrutti per operazioni semplici che fanno tutti i programmi

Il linguaggio di programmazione visuale proposto finora è stato sviluppato


specificamente per risolvere un particolare problema computazionale, far mangiare
tutte le carote presenti su un percorso ad un coniglio. Ovviamente, esistono anche
altri linguaggi di programmazione visuale che sono più general-purpose, ovvero che
permettono di sviluppare algoritmi per risolvere problemi computazionali di vario
genere. Uno di questi è Blocky, creato da Google. Questo linguaggio mette a
disposizione diversi costrutti propri dei linguaggi di programmazione tradizionali, ma
li propone sotto forma di blocchetti che si possono incastrare uno sull’altro o uno
dentro l’altro per definire le sequenze di operazioni di un algoritmo.

Un altro linguaggio di programmazione visuale


Il linguaggio di programmazione visuale proposto finora è stato sviluppato
specificamente per risolvere un particolare problema computazionale. Esistono
anche altri linguaggi di programmazione visuale che sono più general-purpose,
ad esempio Blockly di Google. Questo linguaggio mette a disposizione diversi
costrutti propri dei linguaggi di programmazione tradizionali, ma li propone sotto
forma di blocchetti che si possono incastrare uno sull’altro o uno dentro l’altro per
definire le sequenze di operazioni di un algoritmo

Iterazioni con Blocky e Python


Modalità di istruzione di un computer in modi diversi

istruzioni = list()
iterazione = 0
while iterazione < 4:
iterazione = iterazione + 1
istruzioni.append("avanti")
istruzioni.append("avanti")
istruzioni.append("gira a destra")

Diagramma di flusso di fib(n)


Calcolare ennesimo numero nella sequenza di Fibonacci in cui si usano solo numeri
interi positivi.

Introduzione di due variabili a e b che devono tener conto dei due numeri precedenti
della sequenza – imposto a e b uguale a uno e si imposta ciclo di generazione di
serie di Fibonacci per generare virtualmente i numeri

def fib(n):
if n <= 0:
return 0
elif n <= 2:
return 1
else:
a = 1

b = 1
while True:
c = a + b
if n <= 3:
return c
a = b
b = c
n = n - 1

Una traccia di esecuzione

I casi di 1 e 2 sono semplici perché restituisce sempre 1 e termina l’algoritmo.


Input n a b c Risultato

3 3 1 1 2 2

4 4 1 1 2

3 1 2 3 3

5 5 1 1 2

4 1 2 3

3 2 3 5 5

6 6 1 1 2

5 1 2 3

4 2 3 5

3 3 5 8 8

27/03
Cosa succede quando si clicca su un collegamento ipertestuale (o link) di una
pagina Web?

Per rispondere pienamente a questa domanda, è necessario avere delle


conoscenze di base relative sia sul come l’informazione viene trasmessa
digitalmente, sia sulle componenti che compongono Internet e il Web

La nascita degli ipertesti


Un ipertesto è un corpo di materiale scritto interconnesso in modo così tanto
complesso che non è conveniente presentare su carta . Seppur, al giorno d’oggi,
siamo abituati ad utilizzare questo tipo di strumento, essendo il Web di fatto un
gigantesco ipertesto, una settantina di anni fa quest’idea era praticamente non
convenzionale e non realizzabile. L’idea embrionale dell’ipertesto sembra sia stata
affrontata ben prima della sua proposta formale, essendovi diversi riferimenti già in
letteratura a possibili costruzioni prettamente ipertestuali – ad esempio, si veda il
racconto “Il giardino dei sentieri che si biforcano” di Jorge Luis Borges. Tuttavia,
l’idea di una esemplificazione tecnologica si ha soltanto nel 1945, a seguito
delle riflessioni contenute nel famoso articolo “As We May Think” di Vannevar
Bush. Vannevar Bush, è stato un famoso ingegnere ed inventore statunitense, e fu a
capo dell’Agenzia Federale per la Ricerca e lo Sviluppo durante la seconda guerra
mondiale. Nel suo famoso articolo pubblicato in The Atlantic Monthly, Bush affronta
il problema della crescita esponenziale delle pubblicazioni, a carattere accademico e
non, conseguenza delle nuove scoperte scientifiche, che necessitano di essere
divulgate, e ai meccanismi di produzione sempre più industrializzati.

Facendo continui riferimenti alla divulgazione accademica come principale dominio


di discussione, Bush metteva in evidenza come i meccanismi, che all’epoca
venivano ancora usati per trasmettere e/o revisionare i risultati di una ricerca, erano
molto vecchi e per niente adatti a facilitarne la divulgazione. Se non si fosse
intervenuti per tempo, ci sarebbe stato il rischio di perdere importanti pietre
miliari della ricerca all’interno di una massa sempre più corposa di materiale
irrilevante. In aggiunta, quel che emergeva dalla sua trattazione era che l’attuale
tecnologia, o almeno quella in fase di sperimentazione, poteva già dare largo
supporto alla creazione di piattaforme elettro-meccaniche che semplificassero
notevolmente il salvataggio, la ricerca, e la consultazione di materiale
rilevante. Mentre il problema dello spazio su cui salvare tutte le informazioni poteva
essere affrontato mediante l’uso di tecnologie di frontiera, come i microfilm (grazie ai
quali, secondo Bush, era possibile salvare un’intera copia dell’Enciclopedia
Britannica all’interno di un supporto grosso quanto una scatola di fiammiferi), uno dei
problemi, se non il problema maggiore, era avere un meccanismo di facile
accesso alle informazioni e, in particolare, ad altri dati ad esse correlati. Infatti,
secondo Bush, uno dei problemi principali alla consultazione di un qualsiasi
materiale, era la sua organizzazione sequenziale e l’artificialità del meccanismo
di indicizzazione dei contenuti.

Quando una qualsivoglia informazione viene raccolta in un dispositivo di


memorizzazione, questa informazione viene in qualche modo indicizzata
alfabeticamente (si pensi, ad esempio, ad un indice dei nomi alla fine di un manuale)
o numericamente (si pensi, ad esempio, all’indice dei capitoli e sezioni di un libro).
Inoltre, un’informazione può essere contenuta soltanto in un posto specifico, a meno
che non venga in qualche modo duplicata. Per recuperare una certa informazione a
partire dagli indici a disposizione, una persona deve seguire determinate regole in
modo da identificare la posizione in cui tale informazione si trova (si pensi, ad
esempio, ai libri in una biblioteca). Questo processo si ripete nuovamente, e
sistematicamente, ogni qual volta si debba, o si voglia, cercare una nuova
informazione. Come anticipato, Bush ha definito questo meccanismo di
indicizzazione prettamente artificiale perché non è il modo in cui la mente
umana solitamente opera. Infatti, partendo da una specifica informazione, la mente
si sposta istantaneamente alla successiva mediante un processo associativo, ove
un’informazione in qualche modo ne richiama un’altra, conformemente a una
complicata rete di pensieri veicolata dalle cellule che compongono il nostro cervello.

L’idea di Bush è che questa selezione di informazioni mediante meccanismi


prettamente associativi può essere meccanizzata e conseguentemente esplicitata
in una macchina. Ovviamente, seppur Bush pensasse che non fosse possibile
raggiungere la stessa velocità e flessibilità della mente umana (anche se le attuali
ricerche sui big data sembrano oggi suggerire il contrario), sarebbe quantomeno
stato possibile battere la mente umana relativamente alla permanenza e al recupero
nel tempo delle informazioni se queste fossero state memorizzate su dispositivi
appropriati, ad esempio i microfilm. Nel suo articolo, Bush presentava, in linea
totalmente teorica, una macchina chiamata memex che avrebbe permesso di
salvare tutti i libri, record di dati, e comunicazioni di vario genere su dispositivi
appropriati, così da accedervi in modo completamente meccanico, flessibile, e
veloce.

In particolare, il memex era composto da una scrivania con due schermi al centro
per facilitare la lettura dei documenti memorizzati, accompagnati da una tastiera, un
insieme di bottoni e leve (a destra), e, sulla sinistra, una plancia su cui posizionare
qualunque documento così da essere fotografato e memorizzato nei microfilm
utilizzati dalla macchina.Tutte le informazioni memorizzate (ad esempio, un libro)
potevano, ovviamente, essere recuperate mediante il classico meccanismo a indici
descritto sopra, e consultate attraverso l’uso delle leve messe a disposizione dalla
macchina, che permettevano di sfogliare sequenzialmente documenti. Inoltre, la
macchina metteva a disposizione anche un meccanismo per annotare i documenti
visualizzati, così da aggiungere note a margine, commenti, e quant’altro.

In aggiunta a questo, il più grande vantaggio che il memex avrebbe introdotto era la
possibilità di creare percorsi tra le informazioni, ovvero dei collegamenti
associativi tra le varie porzioni di informazioni memorizzate nel memex.

In particolare, un utente avrebbe potuto creare uno specifico percorso associativo e


memorizzarlo nella macchina con un nome, così da poterlo richiamare ed estendere
in futuro. In questo caso, il memex avrebbe permesso non solo di spostarsi
sequenzialmente sul documento visualizzato, ma anche trasversalmente su diversi
documenti seguendo tutti i percorsi associativi che un utente avrebbe potuto creare.
Infine, avrebbe anche potuto salvare il percorso in uno specifico microfilm così
da poterlo condividere con un collega, che avrebbe potuto visualizzarlo nel suo
memex.

Le idee contenute nell’articolo di Vannevar Bush erano visionarie e d’avanguardia


per l’epoca, e alcune di queste rappresentano ancora dei possibili desiderata dello
sviluppo degli ipertesti e, più in generale, del Web. Molti ingegneri e inventori sono
stati ispirati da quest’articolo nel corso degli anni successivi. Tra questi è bene
ricordare Theodor (Ted) Holm Nelson che ha coniato la parola ipertesto.
Nel 1960, Ted Nelson aveva iniziato a lavorare ad un nuovo progetto, chiamato
Xanadu. L’obiettivo del progetto era quello di creare una rete di computer che
potesse essere depositaria dell’intera conoscenza umana e che potesse essere
estesa mediante dei collegamenti ipertestuali bidirezionali che permettessero di
collegare tra loro idee contenute in diversi documenti riprendendo il concetto di
percorsi associativi postulato da Vannevar Bush [Nelson, 1965].

Inoltre, in questo lavoro, Nelson ha introdotto una serie di concetti chiave – ad


esempio: trasclusione e intertwingularity, che non ha corrispettivi in italiano, ma
richiama esplicitamente il concetto di processo associativo della conoscenza tipico
degli esseri umani enunciato da Vannevar Bush – che sono stati fondamenti
pregnanti di tutti gli ipertesti sviluppati successivamente.

Nello stesso periodo in cui Nelson divulgava le sue idee e il suo progetto, un altro
scienziato, Douglas Engelbart, aveva iniziato l’implementazione di un sistema
rivoluzionario per l’epoca, che di fatto permetteva per la prima volta la creazione di
ipertesti su un computer.

Questo sistema, chiamato oN-Line System (NLS) ebbe un impatto dirompente sullo
stato corrente e futuro delle tecnologie informatiche che erano a disposizione
all’epoca. Basti pensare le innovazioni software (le applicazioni e i programmi a
disposizione di un computer) e hardware (ovvero la parte fisica e tangibile di un
computer, come il processore, il disco fisso, la memoria RAM, etc.) che lo sviluppo
dell’NLS aveva portato:

● il concetto di finestre come meccanismo visuale per l’organizzazione di


contenuti e applicazioni di un sistema operativo
● l’ipertesto
● un sistema di videoconferenza
● il mouse
● un sistema di videoscrittura (o word processor in inglese, tipo Microsoft Word)
● un meccanismo (chiamato dynamic linking) per richiedere solo quando
necessario opportune librerie e applicazioni a disposizione sul computer
● meccanismi per il controllo delle versioni dei documenti
● e un editor collaborativo in tempo reale (tipo Google Docs).

Tutte queste cose non esistevano prima di NLS, e sono da lì in avanti state il
fondamento per lo sviluppo dei moderni computer e sistemi operativi.

L’intero sistema, implementato realmente da Engelbart e soci, era stato per la prima
volta mostrato in una famosa sessione dimostrativa nella Fall Joint Computer
Conference del 1968, organizzata dalla Association for Computing Machinery e
dall’Institute of Electrical and Electronics Engineers (le due principali associazioni
internazionali accademiche di informatica), suscitando commenti entusiastici da
parte di tutta la comunità, tanto da aver poi etichettato quella sessione come la
madre di tutti i demo

L'invenzione del World Wide Web


Sono dovuti passare diversi anni dalla madre di tutti i demo, poco più di trenta, prima
di poter assistere ad un’implementazione su scala mondiale di un ipertesto, il World
Wide Web o, più semplicemente, il Web.

L’idea venne ad un giovane scienziato del CERN di Ginevra nel 1989, Tim
Berners-Lee . Il progetto, inizialmente respinto da parte dei suoi superiori con il
famoso commento “vago ma eccitante”, ritrovato qualche anno più tardi da
Berners-Lee stesso su una copia a disposizione del suo capo di allora, venne poi
accettato come progetto collaterale per testare le potenzialità di un nuovo computer
(il NeXT, realizzato dall’omonima azienda di proprietà di Steve Jobs negli anni di
separazione da Apple) che era stato appena comprato dal CERN.

Nell’idea originale di Berners-Lee, il Web avrebbe dovuto essere un ipertesto che


potesse descrivere una varietà di risorse eterogenee, tra cui documenti,
persone, gruppi di persone, organizzazioni, concetti astratti, e quant’altro.
Inoltre, sarebbe dovuto anche essere possibile collegare tra loro queste risorse
mediante l’uso di collegamenti ipertestuali etichettati, in modo da poter
specificare la semantica del collegamento come parte esplicita del link.

Seppur ispirato alle idee di Ted Nelson, l’infrastruttura ideata da Berners-Lee


proponeva alcune semplificazioni, prima tra tutte il fatto che tutti i collegamenti
ipertestuali del Web dovessero essere percorribili in un’unica direzione,
contrariamente all’organizzazione postulata originariamente da Ted Nelson, ove tutti
i collegamenti ipertestuali erano pensati per essere percorribili in una direzione o
nell’altra indistintamente.

Il primo prototipo del Web realizzato da Tim Berners-Lee, tuttavia, aveva


ulteriormente semplificato lo scenario, riducendo ad una soltanto, il documento o
pagina Web, la tipologia di risorse descrivibili e permettendo una sola tipologia di
collegamento ipertestuale, ovvero il semplice riferimento (il documento A fa
riferimento al documento B). In modo da realizzare questa visione, Berners-Lee
sviluppò una serie di tecnologie, basate su altre già esistenti e messe a disposizione
negli anni precedenti, che permettessero agli utenti la creazione di documenti
ipertestuali (l’Hypertext Markup Language, o HTML), di mettere a disposizione i
suddetti documenti ipertestuali sul Web (attraverso la creazione di server web), di
poterli richiedere mediante l’utilizzo di un opportuno identificativo (chiamato Uniform
Resource Locator, o URL) e di uno specifico protocollo di comunicazione (l’Hypertext
Transfer Protocol, o HTTP), e infine di visualizzarli su un computer (attraverso l’uso
di un browser). Tutte queste tecnologie sono tutt’ora in uso e rappresentano le
fondamenta del Web, seppur questo si sia evoluto molto negli ultimi anni e si sia
sempre più conformato all’idea iniziale che aveva Tim Berners-Lee, che prende il
nome di Web Semantico.

Uniform Resource Locator (URL)


Quando si legge una pagina web, il computer non mostra tutto quello che conosce
sui link ipertestuali presenti in quella pagina. Dentro quel frammento di testo
sottolineato e solitamente colorato in blu (o in viola, nel caso sia stato già visitato)
che può essere cliccato, c’è nascosto un oggetto invisibile che inizia per “http://” (o, a
volte, “https://”, dipendentemente dai casi).

Quell’oggetto è un Uniform Resource Locator, o URL. Un URL rappresenta, di fatto,


una sorta di nome (o più propriamente, un indirizzo) della pagina web a cui il link
punta e permette di accedere cliccandoci sopra. Per esempio, la pagina web su
Wikipedia che parla di URL presentata nel link precedente è identificata dall’URL
http://it.wikipedia.org/wiki/Uniform_Resource_Locator.

In generale, la forma di un qualunque URL presente nel Web è conforme con la


seguente struttura (ove gli elementi tra parentesi quadre sono opzionali):

<schema>://<host>[:<porta>][/<percorso>][?<interrogazione>][#<frammento>]

Le varie parti sono descritte come segue:

● schema – il protocollo di comunicazione usato (tipicamente “http” o “https”)


per richiedere informazioni sulla risorsa indicata dall’URL. Se si pensasse,
metaforicamente, ad un URL come un modo per descrivere la locazione di
uno specifico oggetto all’interno di una casa, il protocollo identificherebbe il
mezzo di trasporto usato (ad esempio una macchina di proprietà, un taxi, un
autobus) per raggiungere la casa che contiene il suddetto oggetto dal luogo in
cui ci si trova.
● host – il nome o una sequenza numerica associata al server web (un
computer “speciale” parte del Web) che ha a disposizione le informazioni
della risorsa identificata dall’URL. Riprendendo la metafora precedente, è
l’indirizzo che identifica la particolare casa che contiene l’oggetto che si vuol
raggiungere – non per niente, di solito, gli URL che specificano soltanto lo
schema e il server restituiscono una risorsa che viene comunemente
chiamata home page (ad esempio https://www.repubblica.it)
● porta – il numero che identifica il particolare servizio a disposizione sul server
web a cui si vuole inoltrare la richiesta per avere informazioni sulla risorsa
indicata dall’URL. In questo caso, è come se la casa in cui si vuole accedere
avesse a disposizione diverse entrate – per esempio la principale, quella che
affaccia sul giardino, o quella sul retro – e se ne deve scegliere una per poter
accedervi. Nel caso questo componente non venga specificato nell’URL, si
assume sempre di usare la porta di default associata al protocollo specificato
(80 nel caso di “http”, 443 nel caso di “https”), che metaforicamente significa
accedere alla casa usando l’ingresso principale.
● percorso – la sequenza di locazioni all’interno del server web, separate da “/”,
da raggiungere per ottenere la risorsa indicata dall’URL. A livello generale, un
server web è uno speciale computer elettronico che ha memorizzati diversi
documenti, organizzati in diverse cartelle, esattamente come siamo abituati a
organizzare i nostri documenti nei nostri computer. In pratica, il percorso di un
URL identifica esattamente una risorsa all’interno di questo computer
speciale. Metaforicamente, una volta entrati nella casa, il percorso potrebbe
essere usato per indicare la sequenza di locali della casa che devo
attraversare per arrivare alla stanza che contiene l’oggetto che mi interessa,
indicato come ultimo elemento del percorso – ad esempio, “scale a sinistra /
primo piano / corridoio / seconda porta a destra / camera dei bambini”.
● interrogazione – è una sequenza di coppie chiave=valore, separate da “&”,
che è possibile comunicare al server web in modo da eseguire determinate
operazioni sulla risorsa indicata dall’URL. Nell’esempio precedente, è
come se, per esempio, potessimo chiedere alla casa di eseguire determinate
azioni, come accendere le luci della camera in cui ci troviamo
● frammento – una sequenza di caratteri che permette di identificare una parte
o una posizione specifica all’interno della risorsa indicata dall’URL.
Utilizzando sempre la metafora precedente, è come se avessimo la possibilità
di indicare uno specifico oggetto presente nella camera dei bambini della
casa in cui siamo entrati, ad esempio il letto a castello dei bambini.

L’URL di Wikipedia introdotto precedentemente a scopo esplicativo presenta solo


alcuni dei precedenti componenti, in particolare:

● lo schema specificato è “http”, che identifica l’uso del relativo protocollo, che
approfondiremo nei capitoli successivi;
● l’host specificato è “it.wikipedia.org”, che identifica il nome del server web che
contiene la risorsa a cui siamo interessati;
● il percorso specificato è “/wiki/Uniform_Resource_Locator”, che indica di
cercare la risorsa “Uniform_Resource_Locator” all’interno della locazione
“wiki”.

Questi tre componenti sono, di solito, i principali utilizzati negli URL presenti nel Web
e nascosti dietro i link ipertestuali che sono specificati in una pagina Web. Ogni qual
volta che, da un proprio dispositivo (un computer, uno smartphone, etc.), si clicca su
un link, il dispositivo stesso recupera una copia della risorsa (ad esempio, della
pagina Web) a cui l’URL si riferisce, per poi visualizzarla a video. Quindi, seppur noi
implicitamente diciamo che, a seguito di un click su un link, noi ci spostiamo da una
pagina web ad un’altra, quel che davvero accade è che il dispositivo usato per
“navigare” tra le pagine web in realtà scarica interamente e localmente una copia
della pagina web a cui si vuole arrivare, e poi la visualizza. Queste azioni sono di
fatto implementate, indipendentemente dal dispositivo usato, da una specifica
tipologia di applicazioni chiamate browser web (o, più semplicemente browser),
introdotta di seguito.

I browser: cosa sono e a cosa servono:


Un browser è un’applicazione software che permette di accedere e ottenere le
informazioni presenti nel Web, così da poterlo “navigare”, come si dice in gergo.
Internet Explorer, Firefox, Microsoft Edge, Safari, Google Chrome sono tutti esempi
di browser.

Il primo browser della storia si chiamava WorldWideWeb, come il Web stesso,


creando non poca confusione all’inizio. Era stato sviluppato da Tim Berners-Lee
come applicazione per il computer NeXT in modo da permettere ad un utente di
navigare tra le pagine del Web allora presenti – la cui prima pagina è ancora
custodita negli spazi dedicati a Tim Berners-Lee del sito web del World Wide Web
Consortium, un’organizzazione non governativa e internazionale fondata da Tim
Berners-Lee per governare, nel modo più comunitario possibile, l’evoluzione del
Web.

Il funzionamento di un qualunque browser, incluso il primo sviluppato, segue sempre


il medesimo schema. Come anticipato, ogni risorsa presente nel Web – sia essa una
pagina web, un’immagine, un documento PDF e quant’altro – è identificata da un
certo URL. Il browser permette di specificare quell’URL in un apposito campo della
sua interfaccia, solitamente in alto, in modo da poter scaricare in locale le
informazioni relative alla risorsa indicata dall’URL e, a seconda del tipo di risorsa,
permette di visualizzarla all’interno della finestra browser (ad esempio nel caso di
una pagina web) o di salvarla in uno specifico documento nel proprio computer (ad
esempio nel caso di un documento PDF). Nel primo caso, la pagina web visualizzata
è un documento ipertestuale a tutti gli effetti: può contenere dei link che, se cliccati,
indicano al browser di richiedere e scaricare la risorsa identificata dall’URL del link
stesso così da visualizzarla.

Sebbene si dica che un browser viene usato per “navigare” il Web, questa
navigazione non è effettiva ma solo metaforica, siccome non ci si sposta fisicamente
da una pagina web ad un’altra come se prendessimo un autobus per muoverci tra le
varie fermate di una città. Piuttosto, il browser richiede sempre una copia della
risorsa identificata da un certo URL, la salva localmente in una locazione privata, e
poi la visualizza a video o ne permette il salvataggio in una locazione a scelta del
dispositivo che si è usato per accedere a quella risorsa.
28/03

Che cos’è un protocollo di comunicazione


Formalmente, un protocollo di comunicazione è un insieme di regole che due
entità, parte di un sistema di comunicazione, devono seguire per scambiarsi
informazioni. Informalmente, può essere considerato come un linguaggio comune,
nel senso proprio del termine, usato da due entità in modo da poter comunicare fra
loro. Infatti, ogni protocollo definisce una specifica sintassi da seguire per costruire
i messaggi, accompagnata da determinate regole interpretative del messaggio
così da definirne anche la semantica. Inoltre, solitamente, un protocollo di
comunicazione prevede anche dei meccanismi per sincronizzare la comunicazione e
per correggere e/o gestire eventuali errori che possono intercorrere nello scambio
dei messaggi.

Protocolli di varia natura, anche informali, sono utilizzati nella vita di tutti i giorni
quando vogliamo, per esempio, comunicare con qualcuno. In questo caso, mentre la
sintassi della lingua è veicolata da opportune regole, e la semantica delle varie
parole che compongono il messaggio è stata appresa nel tempo con
l’apprendimento della lingua stessa, le altre componenti del protocollo derivano
principalmente da regole sociali (ad esempio, il parlare uno alla volta) e dalle proprie
conoscenze (ad esempio, riproponendo il senso di un messaggio usando differenti
costrutti se è poco chiaro all’interlocutore) e dall’ambiente circostante (ad esempio,
alzando la voce per farsi sentire meglio).

Come funziona l’Hypertext Transfer Protocol (HTTP)


L’Hypertext Transfer Protocol, o HTTP è un protocollo di comunicazione
inizialmente sviluppato da Tim Berners-Lee per facilitare l’implementazione del Web,
e poi migliorato ed esteso negli anni successivi – ad esempio con il protocollo
HTTPS, che altri non è che un’estensione di HTTP che implementa un protocollo di
comunicazione più sicuro sul Web, in particolare quando è necessario trasmettere
dati di autenticazione come nomi utenti e password.

HTTP è un protocollo basato su metodi di comunicazione di richiesta-risposta,


tipico di molti protocolli (anche informali) di comunicazione – si pensi, ad esempio, al
protocollo che regola le telefonate, dove un richiedente chiama (la richiesta) un
ricevente che accetta la chiamata (la risposta) per iniziare la conversazione.

Nel caso di HTTP, un client (l’agente che fa la richiesta, ad esempio un browser)


manda un messaggio di richiesta di una specifica risorsa, identificata da un URL, ad
un server (l’agente che dovrebbe avere informazioni su quella specifica risorsa, ad
esempio un server Web), che restituisce al client un messaggio di risposta.

La composizione di questo messaggio di risposta dipende da diversi fattori – ad


esempio se la risorsa è o non è presente sul server, se è stata spostata in un’altra
locazione, etc. – e, anche, dal tipo di richiesta effettuata dal client.

Le tipologie di richieste che possono essere effettuate da un client vengono definite


grazie all’uso di uno specifico metodo, ovvero l’operazione di richiesta relativa
all’URL coinvolto nella comunicazione.

In pratica è come se, quando si comunica con qualcuno, si avesse la possibilità di


scegliere tra alcune possibili operazioni che il ricevente deve eseguire, che possono
andare dalla semplice richiesta di informazioni (ad esempio, quando chiamiamo la
banca per sapere lo stato del nostro conto), ad azioni più operative che determinano
l’esecuzione di una specifica azione da parte del ricevente (ad esempio, quando
chiamiamo la banca per far emettere un bonifico).

Il metodo più usato nel Web è sicuramente GET, che permette di richiedere
informazioni sulla risorsa definita dall’URL specificato.

GET viene usato ogni qual volta richiediamo di visitare una specifica pagina
web, per esempio come conseguenza di un click su un collegamento ipertestuale.
Altri metodi largamente usati sono:

● PUT permette di creare sul server web contattato la risorsa specificata


dall’URL utilizzato nella richiesta, e di associare le informazioni, relative ad
essa, incluse nella richiesta effettuata;
● DELETE permette di rimuovere dal server web contattato tutte le informazioni
relative alla risorsa specificata nella richiesta tramite l’URL;
● POST permette di specificare informazioni aggiuntive, incluse nella richiesta,
ad una risorsa esistente che già risiede sul server.

Tuttavia, mentre GET è preponderante nel Web, visto che viene usato per richiedere
una qualsiasi risorsa, gli altri metodi non sempre sono liberamente utilizzabili da tutti
i client. Sta sempre al server web decidere quali di questi metodi possano essere
usati nella comunicazione.

Tutti i metodi HTTP sono classificabili a seconda che siano conformi o meno a due
caratteristiche specifiche, ovvero se sono safe e/o se sono idempotenti.
❖ Un metodo si dice safe quando viene usato solo per recuperare delle
informazioni dal server web, senza cambiarne lo stato, ad esempio
aggiungendo nuovi dati.

Il metodo GET è un metodo safe, considerando che viene usato soltanto per
richiedere informazioni relativamente ad una specifica risorsa, mentre PUT non lo è
perché viene usato per creare una nuova risorsa sul server web.

❖ Invece, un metodo si dice idempotente se molteplici richieste effettuate allo


stesso URL hanno lo stesso effetto, sul server web, che effettuare una
sola richiesta. Anche in questo caso, il metodo GET, così come PUT e
DELETE, sono metodi idempotenti, mentre POST non lo è, perché diverse
richieste POST identiche possono di fatto generare comportamenti
differenti.

A prescindere dal metodo usato per la comunicazione, tutti i messaggi di ogni


richiesta e risposta veicolano due tipi di dati ben distinti:

● i metadati relativi alla comunicazione – come il nome di client usato per


effettuare la richiesta, il nome del server web che dovrebbe avere a
disposizione la risorsa, etc.
● eventuali dati (o contenuto) da accompagnare al messaggio. Per esempio, in
una conversazione telefonica, il chiamante come prima cosa introduce chi è al
ricevente (i metadati della comunicazione), per poi passare ad esplicitare il
motivo della chiamata e le informazioni che si vorrebbero ottenere (il
contenuto della comunicazione).

Considerando i messaggi consegnati utilizzando il protocollo HTTP, queste due


tipologie di informazioni, ovvero i metadati e i dati, sono contenute in due
specifiche sezioni del messaggio, rispettivamente chiamate intestazione
(header) e contenuto (payload).

Tipicamente, una qualunque richiesta o risposta ha sempre l’header specificato,


mentre il payload può contenere informazioni come no.

Per esempio, quando si richiede una pagina web attraverso un browser, viene
effettuata una richiesta ad un certo URL contenente soltanto i metadati nell’header,
mentre il payload è completamente vuoto. Al contrario, la risposta del server web
contiene sia informazioni nell’header sia un vero e proprio documento nel payload,
ovvero la pagina web che deve essere visualizzata sul browser richiedente, nel caso
tale informazione sia a disposizione del server web a cui è arrivata la richiesta.

Tutte le risposte, oltre che a contenere metadati nell’header e, talvolta, dati nel
payload, specificano anche un codice di stato che indica se la richiesta è
andata a buon fine o se sono intercorsi dei problemi.
→ Un codice di stato è un numero di tre cifre, la cui prima cifra (da 1 a 5) definisce
la classe di risposta, mentre le altre due sono usate per identificare una specifica
motivazione relativa alla risposta. Le cinque classi di risposta sono:

1. risposta informativa – la richiesta è stata ricevuta e correttamente


compresa, e sono necessari alcuni passaggi aggiuntivi (attendere, cambiare
protocollo, etc.) per poter ottenere le informazioni sulla risorsa richiesta;
2. successo – la richiesta è stata ricevuta, correttamente compresa, e
accettata;
3. redirezione – il client deve effettuare specifiche azioni aggiuntive per
completare la richiesta (ad esempio, cercare le informazione sulla risorsa ad
un altro URL);
4. errore del client – la richiesta presenta un qualche errore lato client (ad
esempio, non si ha il permesso di accedere alla risorsa, non è stata trovata
alcuna informazione associata alla risorsa, etc.) e non può essere soddisfatta;
5. errore del server – il server web ha incontrato un qualche problema nel
soddisfare la richiesta (ad esempio, server non è disponibile al momento a
causa di un sovraccarico di gestione, non supporta il protocollo HTTP
utilizzato dalla richiesta, etc.).

Mentre i codici della classe 1 sono solitamente abbastanza rari, i più comuni, in una
comunicazione HTTP, sono i seguenti (tra parentesi le etichette esplicative ufficiali):

● codice 200 (OK) – la richiesta è stata soddisfatta con successo;


● codice 303 (See Other) – la risposta alla richiesta può essere trovata ad un
altro URL;
● codice 400 (Bad Request) – la richiesta non può essere processata dal
server;
● codice 403 (Forbidden) – la richiesta è valida, ma il client non ha i permessi
necessari per accedere alle informazioni relative alla risorsa richiesta;
● codice 404 (Not Found) – le informazioni relative alla risorsa richiesta non
sono state trovate;
● codice 500 (Internal Server Error) – un errore generico lato server non ha
permesso il corretto processamento della richiesta;
● codice 503 (Service Unavailable) – il server è temporaneamente non
disponibile.

Per riassumere: ogni qual volta un client manda una richiesta HTTP, utilizzando uno
dei metodi HTTP a disposizione, relativamente ad una certa risorsa identificata da
un URL, in realtà manda uno specifico messaggio contenente informazioni
generali sulla richiesta (i metadati, contenuti nel campo header del messaggio) e,
eventualmente, dei dati (il payload del messaggio) ad un server destinatario in
qualche modo codificato all’interno dell’URL della risorsa richiesta.
Il destinatario, letto il messaggio, restituisce risposta affermativa, con codice di stato
200, accompagnata dal relativo messaggio di risposta se può evadere la richiesta
correttamente, altrimenti restituisce un opportuno messaggio di errore, così da
rendere esplicito al mittente cosa non ha funzionato nella comunicazione.

Che cos’è un server web


Un server web è un computer “speciale” che esegue un software specifico che
permette di ricevere, gestire, e soddisfare richieste HTTP provenienti da un client, ad
esempio un browser.

Il nome del server web è incluso nell’URL che identifica la risorsa di cui si vuole
ottenere informazioni, nella parte host, come introdotto nel capitolo precedente (ad
esempio it.wikipedia.org). Tuttavia, la forma corretta e completa della richiesta HTTP
mandata dal client non è quella semplicistica introdotta precedentemente col solo
URL, ma è strutturata in modo preciso, in modo da identificare i vari componenti che
ne fanno parte, incluso il nome del server web da contattare.

In particolare, quando un client (ad esempio, un browser) richiede informazioni su


una specifica risorsa (ad esempio una pagina web) utilizzando l’URL relativo, la
richiesta che viene davvero effettuata ha la seguente forma, dove ogni parte della
richiesta è di fatto derivata dall’URL:

<metodo HTTP> <percorso> <protocollo>


HOST: <nome del server>

Ad esempio, quando si vuole accedere alla pagina web all’URL


http://it.wikipedia.org/wiki/Uniform_Resource_Locator, la richiesta effettuata dal
browser viene strutturata come segue:

GET /wiki/Uniform_Resource_Locator HTTP/1.1


HOST: it.wikipedia.org

Una volta che il server web riceve una richiesta fatta in questo modo, cerca
localmente informazioni del documento indicate nel percorso della richiesta e,
una volta trovate, le impacchetta in un nuovo messaggio di risposta, restituendole
al richiedente.

Seppur noi, utilizzatori di client come i browser, cerchiamo di accedere ad una


risorsa a disposizione in un certo server web usando il nome di quest’ultimo,
it.wikipedia.org nell’esempio precedente, in realtà il server web non è direttamente
raggiungibile usando il suo nome, ma avviene una cosa molto simile a quello che
succede con una comunicazione telefonica.
In pratica, quando dobbiamo chiamare qualcuno col nostro cellulare, cerchiamo
questa persona nella nostra rubrica attraverso il suo nome, e chiediamo al nostro
cellulare di iniziare una chiamata telefonica. Tuttavia, quello che davvero fa il
cellulare, è di prendere il numero di telefono associato a quella persona e di attivare
la comunicazione mandando una richiesta di telefonata a questo numero.
Ovviamente, in alternativa, si potrebbe anche digitare direttamente il numero di
telefono della persona che si vuol chiamare se si conosce a memoria, senza
necessariamente cercarla in rubrica.

Scenario analogo anche quando un client richiede una pagina web ad un server
web.

Infatti, un qualunque server web è identificato in modo univoco da una sequenza di


quattro numeri separati da punti, ad esempio 130.136.130.1, ove ogni numero
può essere un valore che va da 0 a 255.

Questo numero si chiama indirizzo IP, dove “IP” è l’acronimo di “Internet Protocol”.
Ogni volta che si fa una richiesta HTTP, in qualche modo viene recuperato l’indirizzo
IP del server web a cui mandare la richiesta partendo dal nome di questo indicato
nell’URL – il campo host – per poi inviare il messaggio esplicitamente a
quell’indirizzo, menzionando esplicitamente qual è il nome del server a cui il
messaggio deve essere rivolto – nell’esempio sopra HOST: it.wikipedia.org.

29/03

RIASSUNTO: Quando si clicca su un link di una pagina web visualizzata attraverso


un browser, il browser crea un messaggio di richiesta che specifica il metodo HTTP
utilizzato per la richiesta, ovvero GET, il server web a cui la richiesta deve essere
fatta, e il percorso della risorsa richiesta. Il messaggio arriva, in qualche modo, al
server web, identificato da un numero univoco chiamato indirizzo IP. Il server web
elabora la richiesta e, se soddisfacibile, crea un nuovo messaggio di risposta, a cui è
associato uno specifico codice di stato a seconda del tipo di risposta da restituire,
che include una copia della pagina web richiesta nel corpo del messaggio. Una volta
che questa copia viene ricevuta dal browser, questi la visualizza (nel caso sia una
pagina web, per esempio) o ne permette la memorizzazione all’interno del
dispositivo da cui è partita la richiesta attraverso il browser usato.

La nascita di Internet
La prima cosa da evidenziare chiaramente è che Internet non è sinonimo di Web –
infatti, i due concetti si riferiscono a due entità distinte.

Semmai, si può dire che il Web è uno dei più famosi servizi di Internet – non il
solo, basti pensare alla e-mail, il trasferimento di documenti, o sistemi Voice over IP
per comunicazioni audio e/o video come Skype o WhatsApp – perché si basa
interamente sulle tecnologie messe a disposizione da Internet.
La parola Internet in realtà è una contrazione di interconnected network, rete
interconnessa in italiano, che è composta da tante altre reti più piccole di dispositivi
(computer, cellulari, etc.) interconnessi tra loro mediante l’uso di specifici protocolli di
comunicazione.

→Il concetto principale dietro la realizzazione di Internet è che doveva essere


un’infrastruttura generale che potesse permettere la creazione di nuove
applicazioni

Storicamente, le ragioni principali che hanno portato alla nascita di Internet sono da
recuperare negli anni immediatamente successivi alla seconda guerra mondiale, in
corrispondenza delle tensioni internazionali che erano nate tra Russia e Stati
Uniti → guerra fredda.

→primi esperimenti atomici effettuati dalla Russia → sviluppo della realizzazione di


missili balistici intercontinentali, uno degli obiettivi primari degli Stati Uniti era
quello di provvedere ad una creazione di una rete di comunicazione che fosse
abbastanza robusta da garantire la comunicazione tra tutti gli stati anche in
seguito ad un attacco missilistico molto rilevante, ad esempio con testate
nucleari.

Nel 1958, in risposta al lancio dello Sputnik 1 (primo satellite artificiale mandato in
orbita intorno alla Terra) da parte dei Russi, era stata fondata la Advanced Research
Projects Agency (ARPA), responsabile per la ricerca e lo sviluppo di tecnologie
emergenti con forte applicabilità a livello militare, che coinvolgeva esperti
provenienti da diverse realtà: industriale, accademica, e governativa

ARPA finanziò anche l’oN-Line System sviluppato da Douglas Engelbart, ma


soprattutto l’Advanced Research Projects Agency Network (ARPANET),
comunemente definito il precursore di Internet.

Il primo responsabile del programma Command and Control Research di ARPA,


Joseph Carl Robnett Licklider , fu il visionario che già nel 1962 iniziò a parlare di
Galactic Network , ovvero un insieme di computer interconnessi a livello globale
attraverso il quale chiunque avrebbe potuto accedere a dati e programmi da ogni
punto di accesso a disposizione. Seppur non fosse più in ARPA nel momento in cui
ARPANET fu finanziata, riuscì a convincere il suo successore, Ivan Sutherland, che
il progetto era meritevole di essere proseguito.

Il primi nodi di ARPANET furono installati nel Network Measurement Center della
University of California Los Angeles (UCLA) e lo Stanford Research Institute (SRI).

→Il primo messaggio della storia, fu inviato da Charles S. Kline, uno studente
universitario, il 29 ottobre 1969 da un computer del laboratorio di Leonard Kleinrock
dell’UCLA ad un computer dello SRI.
→Il contenuto del messaggio era la stringa “lo” – doveva inizialmente essere la
parola “login”, ma dopo l’invio dei primi due caratteri il sistema si bloccò, e venne
ripristinato solo un’ora più tardi.

Negli anni successivi, i nodi della nuova rete ARPANET crebbero notevolmente fino
ad arrivare a 61 nel luglio del 1977 →la rete venne ufficialmente e pubblicamente
mostrata solo nel 1972 durante la prima International Computer Communication
Conference a Washington – anno in cui venne anche dimostrata una delle prime
applicazioni di ARPANET, la posta elettronica (o e-mail) sviluppata da Ray
Tomlinson.

Durante questi anni, furono sviluppate le tecnologie e i protocolli chiave che hanno
permesso la nascita di Internet tra tutti la tecnica a commutazione di pacchetto per
l’invio e la ricezione dei dati e la suite di protocolli Internet (TCP/IP).

Dopo ARPANET, diverse reti sono iniziate a sorgere, inizialmente negli Stati Uniti e
poi nel resto del mondo. Tra le più importanti si ricordano:

● Computer Science Network (CSNET), finanziata nel 1981 dalla National


Science Foundation (NSF) per collegare i dipartimenti di informatica delle
varie università americane che non erano già collegate ad ARPANET;
● National Science Foundation Network (NSFNET), finanziata qualche anno
dopo la precedente sempre dalla NSF per collegare tra loro i centri che
mettevano a disposizione i supercomputer finanziati dalla stessa NSF;
● NASA Science Network (NSN), finanziata a metà degli anni ottanta dalla
National Aeronautics and Space Administration (NASA).

La suite di protocolli TCP/IP →lo strumento grazie al quale tutte queste reti sono
state intercollegate tra loro, permettendo per la prima volta la comunicazione tra
computer collegati a reti differenti.

La nascita di Internet avviene di fatto alla fine degli anni ottanta, quando ARPANET e
NSFNET vengono intercollegate tra loro: per la prima volta, due reti differenti (e i
computer che a esse solo collegati) possono “dialogare” tra loro mediante l’utilizzo
dei suddetti protocolli.

Nei successivi anni sempre più reti vennero collegate tra loro in questa gigantesca
infrastruttura, la spinta definitiva del processo di espansione e popolarità della rete
venne dal Governo degli Stati Uniti d’America, in particolare dall’allora senatore Al
Gore →dalla fine degli anni ottanta, campagna di supporto a Internet e alle sue
potenzialità e, in particolare, alla sua drastica estensione, in modo di permettere la
connessione contemporanea di milioni di computer, non solo appartenenti a enti
di ricerca o a industrie, ma (e soprattutto) posseduti da comuni cittadini.

A tal fine, dopo aver anticipato le sue idee in un noto articolo di Scientific American ,
Al Gore introduce un atto, l’High Performance Computing Act of 1991 (HPCA) (o,
informalmente, Gore Bill) firmato dall’allora presidente George H. W. Bush,
prevedeva la creazione di un’enorme rete ultraveloce chiamata National
Research and Education Network (NREN).

Successivi sviluppi del Web e rilascio del primo browser interamente grafico, Mosaic
(1993) hanno permesso la larga diffusione di Internet come fenomeno di carattere
mondiale.

Pacchetti di comunicazione
Oltre ai protocolli di comunicazione utilizzati, ovvero la suite di protocolli Internet
TCP/IP, l’altra grande invenzione che ha permesso la creazione di Internet è il
concetto di pacchetto e di comunicazione a commutazione di pacchetto.

Un pacchetto è un’unità atomica in informazione, formata solitamente da due


componenti:

● l’header, contenente informazioni relative al controllo di una comunicazione


● il payload, ovvero i dati che il pacchetto trasmette.

Solitamente, in Internet, i pacchetti sono caratterizzati da una dimensione massima


in termini di informazione che possono contenere, per cui, quando un mittente vuole
mandare un messaggio attraverso Internet, è necessario spezzare il suddetto
messaggio in diversi pacchetti che verranno inviati nella rete per poi essere ricevuti
dal destinatario del messaggio.

Solitamente, in Internet, un pacchetto contiene, nell’header, gli indirizzi IP del


computer mittente e del computer destinatario del pacchetto, e altre informazioni di
utilità per la comunicazione, come il tempo di vita del pacchetto nella rete, la
dimensione dei dati che il pacchetto contiene, etc.

L’introduzione nell’uso dei pacchetti come meccanismo di comunicazione venne


fatta i primi anni del 1960, in modo indipendente, da due scienziati: Paul Baran e
Donald Davies perfezionata da Leonard Kleinrock, uno dei padri di ARPANET.

L’idea era piuttosto rivoluzionaria per l’epoca e sovvertiva la tecnica allora usata
per le comunicazioni, la commutazione di circuito, imposta dalla Bell, la più grande
compagnia telefonica statunitense dell’epoca.

L’idea della commutazione di circuito è abbastanza semplice. Nel momento in cui un


mittente e un destinatario vogliono attivare una comunicazione, ad esempio
mediante una telefonata, viene stabilito un circuito virtuale unico di comunicazione,
ovvero una sequenza finita e sequenziale di nodi riservati che permette la sola
comunicazione dal mittente al destinatario usando tutta la banda a disposizione,
e che occupa in modo esclusivo i suddetti nodi fino al termine della telefonata.
→viene creato un circuito virtuale dedicato tra mittente e destinatario che occupa
tutta la banda a disposizione, e che non permette l’uso dei nodi del circuito per altre
comunicazioni se non per quella attiva, finché il messaggio non è stato
completamente trasmesso.

Nella comunicazione a commutazione di pacchetto, invece, il messaggio viene,


come anticipato, spezzato in diversi pacchetti, che vengono trasmessi sulla rete
senza occupare l’intera banda di un circuito, e vengono instradati dal mittente al
destinatario seguendo, potenzialmente, percorsi diversi.

Il principale vantaggio di questa tecnica è la sua tolleranza ai guasti, ovvero la


capacità di garantire la comunicazione anche nel caso in cui uno dei
componenti della rete venisse a mancare per una qualsivoglia ragione – ad
esempio, a seguito della distruzione di uno dei nodi della rete mediante l’uso di una
bomba.

→i pacchetti che formano il messaggio sono di fatto indipendenti tra loro, e non
viene preallocata alcuna banda tra i nodi che dividono il mittente e il destinatario.
Inoltre, i pacchetti possono indipendentemente seguire diverse percorsi per giungere
al destinatario finale.

Che cos’è l’Internet Protocol (IP)


In Internet, la comunicazione, ovvero lo scambio di dati tra due computer collegati in
rete, è realizzata mediante l’uso dei pacchetti. Tuttavia, esiste una gerarchia di
incapsulamento dei dati da spedire, definita dalla suite di protocolli Internet TCP/IP,
organizzata in quattro livelli, come mostrato in Figura 6.

Nei pacchetti dello strato più in basso, quello di accesso alla rete, solutamente, oltre
all’header, compare anche un piccolo pezzettino chiamato trailer, che determina la
fine del pacchetto.

Messaggio da inviare da un certo mittente verso un destinatario viene prima messo


dentro una scatola A, che contiene metadati del messaggio sul coperchio (l’header),
e i dati veri e propri al suo interno (il payload). Poi, la scatola viene ricevuta dal
postino, che a sua volta mette l’intera scatola A dentro una nuova scatola B,
anch’essa dotata di nuovi metadati sul coperchio (header) e il cui contenuto
(payload) è l’intero messaggio definito dalla scatola A.

A sua volta, la scatola B viene ricevuta da un centro di distribuzione postale, e viene


inserita all’interno di una nuova scatola C, con dei suoi metadati (header) e con il
contenuto corrispondente all’intera scatola B.

Alla fine, la scatola C viene data ad un corriere che la organizza secondo i suoi
criteri in una nuova scatola D in modo simile all’approccio usato in precedenza negli
altri passaggi, e la fa pervenire al centro di distribuzione più vicino al destinatario.
Questo centro di distribuzione estrae la scatola C, che viene passata all’ufficio
postale più indicato, che a sua volta estrae la scatola B per poi passarla al postino.

Il postino, infine, arriva all’indirizzo di consegna, estrae la scatola A e la consegna al


destinatario, che la apre e ottiene il contenuto di partenza – ovvero il payload
originariamente messo dal mittente dentro la scatola A.

I quattro livelli di incapsulamento informalmente descritti sono realizzati dai


seguenti quattro “strati” definiti dalla suite di protocolli TCP/IP:

● Strato applicazione – creati i dati dell’utente (ad esempio il messaggio di


richiesta per una pagina web) ed è dove i protocolli di alto livello, come HTTP,
agiscono. Questo strato permette la connessione tra applicazioni, ad esempio
un browser con il server web, e non conosce esplicitamente le peculiarità
legate al trasporto di questi dati in Internet, regolate dagli strati successivi;
● Strato trasporto – è lo strato che permette la comunicazione tra il
computer mittente e il computer destinatario, che ospitano le due
applicazioni usate per la comunicazione a livello applicazione. In Internet,
questo strato è regolato dal protocollo TCP
● Strato di rete – è lo strato che permette la comunicazione tra i vari nodi
presenti in Internet, e che di fatto permette l’instradamento dei i vari pacchetti
dal mittente fino al destinatario passando tra le varie reti di cui Internet è
composto. Questo strato è regolato dal protocollo IP
● Strato di accesso alla rete – è lo strato che definisce come i vari messaggi /
pacchetti devono essere instradati all’interno di una specifica rete locale, ove
il protocollo usato dipende fortemente dalla tipologia di rete in considerazione.

→Internet è quell’enorme rete, creata come interconnessione di altre reti più piccole,
che regola i protocolli di comunicazione che permettono a due computer parte
della rete di parlare tra loro, ove il messaggi che si scambiano transitano nella rete
mediante l’utilizzo del meccanismo a commutazione di pacchetto, ed è regolata da
due specifici protocolli (e conseguenti strati): TCP (strato trasporto) e IP (strato
rete).
→Il Web, invece, è quel particolare servizio, basato sul protocollo HTTP e costruito
sopra i protocolli TCP/IP, che permette a due applicazioni (ad esempio un browser e
un server web), presenti su due computer distinti collegati a Internet, di comunicare
tra loro senza conoscere direttamente la topologia della rete e i meccanismi di
instradamento dei messaggi inviati.

→In breve, Internet è l’infrastruttura su cui il Web è stato costruito.

L’Internet Protocol (IP) è il protocollo che regola l’instradamento attraverso i


vari nodi di Internet dei vari pacchetti IP che, in qualche modo, compongono il
messaggio originale. Attualmente, il protocollo IP ha due versioni, entrambe
correntemente utilizzate in Internet: la versione 4 (IPv4, quella usata originariamente
in Internet e attualmente quella più usata) e la versione 6 (IPv6, ovvero quella
rilasciata di seguito per poter gestire un numero maggiore di computer collegati alla
rete).

Il punto cruciale dei pacchetti IP instradati dal protocollo, indipendentemente dalla


versione utilizzata, è che specificano, per ogni pacchetto, l’indirizzo IP del
mittente e l’indirizzo IP del destinatario.

Un indirizzo IP (in base alla versione 4 del protocollo) è una sequenza di quattro
numeri separati da punti, dove ogni numero può assumere un qualsiasi valore tra 0 e
255, ad esempio 130.136.130.1.

Tutti i dispositivi collegati ad Internet sono univocamente identificati da uno


specifico indirizzo IP. Non solo il server web ma anche il computer collegato alla
rete su cui viene eseguito il browser che fa la richiesta della risorsa ad un certo URL
è dotato di indirizzo IP →la differenza tra i due indirizzi IP è che mentre quello del
server web è statico, ovvero non cambia nel tempo, quello del computer su cui è
installato il browser, è dinamico, ovvero cambia ogni qual volta quel computer si
collega a Internet.

È bene sottolineare che è possibile siano necessari più pacchetti IP per recapitare
un messaggio completo da un mittente a un destinatario, perché spesso ogni rete
specifica una dimensione massima per pacchetto che può essere trasportato →
messaggio spezzato in più di un pacchetto IP da consegnare al destinatario.

Considerando questa situazione, emerge un’altra caratteristica tipica del protocollo


IP, ovvero la comunicazione senza connessione. In pratica, i pacchetti IP di un certo
messaggio vengono instradati in modo completamente indipendente tra loro,
visto che ogni pacchetto contiene esplicitamente l’indirizzo del computer a cui deve
essere recapitato.

Nello strato di rete, il mittente e il destinatario non devono mettersi d’accordo prima
di inviare i dati, ma semplicemente agiscono senza conoscere l’eventuale stato
(attivo, non disponibile, etc.) dell’altro →i pacchetti possono perdersi, non arrivare
nell’ordine in cui sono stati mandati, arrivare duplicati.

Il protocollo IP, per la sua natura di essere senza connessione, non è responsabile
della risoluzione di queste problematiche, e demanda tutta la gestione allo strato di
trasporto dei due computer mittente e destinatario coinvolti nella comunicazione,
regolato dal protocollo TCP.

Domain Name Server (DNS) e router


Due aspetti fondamentali per permettere la comunicazione tra il mittente e il
destinatario di un messaggio e il corretto instradamento dei pacchetti →due
domande:

1. Come si fa a recuperare l’indirizzo IP del server web a cui mandare il


messaggio di richiesta preparato dal browser, ovvero i relativi pacchetti IP, se
si ha solo a disposizione il nome del server web (ad esempio,
it.wikipedia.org)?
2. Abbiamo visto che i pacchetti IP vengono instradati attraverso i vari nodi di
Internet prima di arrivare al destinatario, ma cosa sono davvero questi nodi?

Quando Internet era ancora piccola, esisteva una specifica tabella di mappatura
tra il nome dei server web della rete e il relativo indirizzo IP statico che gli era stato
assegnato →mantenuta da uno specifico ente, lo Stanford Research Institute.

Tuttavia, con l’ingrandimento esponenziale di Internet negli anni successivi, avere un


meccanismo centralizzato che mettesse a disposizione queste mappature non era
più gestibile. Per ovviare al problema, agli inizi del 1980 venne creato il Domain
Name System (DNS) → sorta di elenco del telefono di Internet →partendo dal nome
di un server web, ad esempio it.wikipedia.org, permette di ottenere il relativo
indirizzo IP, 208.80.154.224 per esempio.

In Internet, ci sono diversi computer speciali chiamati server DNS, il cui ruolo è
quello di restituire il corretto indirizzo IP per un certo nome a seguito di una richiesta
fatta dal DNS Resolver a disposizione sul computer mittente del messaggio.

Quando si chiede di avere informazioni su una risorsa ad un certo URL, il browser


prima contatta il DNS Resolver a disposizione del computer che lo ospita e gli chiede
di ottenere il relativo indirizzo IP dell’host specificato nell’URL.

Il DNS Resolver contatta il più vicino server DNS che conosce – il cui indirizzo IP è
stato configurato a mano o ottenuto dinamicamente nel momento in cui il computer
mittente si è connesso a Internet – mandandogli la richiesta di risoluzione.

Una volta trovato l’IP, il server DNS restituisce la mappatura al DNS Resolver, che lo
mette a disposizione del browser e, anche ad altre applicazioni → trovato l’indirizzo
del server web da contattare, usato per preparare i vari pacchetti IP da inviare al
computer destinatario.

A livello astratto, ogni nodo di Internet è, di fatto, uno specifico computer che
può avere uno o più ruoli →computer personali di casa servono a noi per collegarci a
Internet.

I server web sono dei computer in grado di interpretare richieste HTTP e, di fatto,
mettono a disposizione pagine web che possono essere richieste in modo da poterle
visualizzare e navigare su un browser. I server DNS sono dei computer che
permettono di recuperare un indirizzo IP a partire da un certo nome di dominio.
Tuttavia, c’è almeno un altro computer speciale, che è fondamentale per il corretto
funzionamento della rete, ovvero il router.

ROUTER: dispositivo di rete esclusivamente dedicato a svolgere un compito molto


peculiare e preciso responsabile dell’instradamento dei pacchetti IP dal mittente
fino al destinatario.

Esistono diversi tipi di router usati in rete dipendentemente dal ruolo che svolgono.
Per esempio, il router per permettere al nostro computer di connettersi a Internet è
responsabile di metterci in contatto con il nostro Internet Service Provider (ISP),
ovvero l’operatore che ci permette di usufruire dei vari servizi di Internet.

I router agiscono principalmente sullo strato di rete e svolgono il ruolo di vigile


urbano di Internet, veicolando il traffico dei pacchetti IP verso il percorso più
appropriato per raggiungere il destinatario.

Quando un router riceve un pacchetto IP, controlla qual è il prossimo nodo a cui il
pacchetto deve essere trasmesso per avvicinarlo al destinatario → identificato
l’indirizzo IP del prossimo nodo, informazione incapsulata in un nuovo pacchetto
dello strato di accesso alla rete → recapitato al nodo identificato.

Router non entra mai nel merito del payload del pacchetto IP che deve trasmettere,
guarda soltanto il suo header per capire dove sia meglio instradare il pacchetto,
consultato la sua tabella di instradamento, aggiornata in modo manuale o
automatico, chiedendo informazioni ad altri router vicini. Una volta spedito il
pacchetto IP, il router non tiene traccia di alcuna informazione ad esso relativa.

Figura 8. Riassunto delle tecnologie che abbiamo


trattato in questo capitolo e nei precedenti – dove
i cerchi azzurri con le frecce bianche sono router.
A seguito di un click su un link di una pagina web visualizzata sul browser di un
computer, viene composta un messaggio HTTP di richiesta di una specifica pagina
web identificata da un URL. Una volta recuperato l’indirizzo IP dal nome del server
web che ha la pagina a disposizione usando il DNS, il messaggio HTTP viene
incapsulato da uno o più pacchetti IP che vengono poi inviati dal computer mittente
al router più vicino – ad esempio il router di casa. Da lì, i pacchetti IP vengono
instradati nella rete finché non raggiungono il server web destinatario, che riceve il
messaggio, e impacchetta una copia del documento richiesto in un nuovo
messaggio HTTP di risposta. A sua volta, questo messaggio viene incapsulato in
uno o più pacchetti IP inviati dal server web al router più vicino, e poi instradati fino
al mittente. Una volta ricevuto, il messaggio di risposta viene passato al browser che
visualizza a video il contenuto del payload del messaggio HTTP.

Byte e bit: unità di informazione


Nello scorso capitolo abbiamo accennato al fatto che un particolare messaggio
debba essere spezzato in uno o più pacchetti IP prima che questi vengano instradati
in rete. Questo è dovuto a due diversi fattori:

● limite dato dalla massima quantità di dati che ogni pacchetto IP può
trasportare (che dipende dalla versione considerata del protocollo, IPv4 o
IPv6)
● limite imposto dalla rete a cui si instradano i pacchetti, ovvero il suo Maximum
Transmission Unit (MTU).

Quindi, anche se tutto il messaggio HTTP possa, in linea di principio, essere


incapsulato dentro un pacchetto IP, è possibile che debba comunque essere
spezzato in più pacchetti IP a causa del limite MTU imposto dalla rete. Questa
frammentazione può avvenire sia nello strato di rete in alcuni casi e solo se si utilizza
il protocollo IPv4 per l’instradamento, o nello strato trasporto, che sarà oggetto di
questo capitolo.

Questi limiti sono espressi in byte:

→Un byte è una delle più diffuse unità di informazione →storicamente corrisponde al
numero di bit necessari per codificare un carattere sul computer →è l'unità minima di
informazione occupabile su un computer elettronico.

→Un byte corrisponde a otto bit, ove con bit (una contrattura di binary digit) si
intende l'unità minima di informazione che si può scambiare in una comunicazione e
che può assumere soltanto uno di due valori: 0 o 1.

Il concetto di bit è stato indirettamente usato da diversi studiosi del passato, per
esempio da Charles Babbage con la sua macchina analitica che proponeva l'uso di
schede perforate, dove la presenza o assenza di un buco in una certa posizione
poteva essere interpretata rispettivamente come l'assegnamento di un 1 o di uno 0.

Prima persona a usare la parola bit fu Claude Shannon nel 1948 in un articolo che
ha segnato la nascita della teoria dell'informazione → riguarda uno specifico campo
di ricerca che studia come quantificare, memorizzare, e scambiare informazione, che
ha tuttora svariate applicazioni pratiche, oltre che aver caratterizzato e veicolato
l’invenzione di diverse tecnologie del passato, incluso lo sviluppo di Internet.

Ad esempio, evincere la capacità massima di un canale per trasmettere


informazione in modo affidabile, è stato uno degli studi della teoria dell’informazione
che caratterizza qualsiasi comunicazione tra una sorgente e un destinatario
attraverso un canale di comunicazione, e ha particolare rilevanza per stabilire, per
esempio, la massima unità di informazione per pacchetto (MTU) in una particolare
rete, accennata in precedenza.

L'idea di base è che ogni carattere, numero, programma, applicazione all'interno di


un computer, come qualunque messaggio da scambiare in Internet, è di fatto
codificato come una sequenza di bit poi riconvertiti con la sequenza di caratteri
corretta dalla particolare applicazione che riceve ed interpreta quell'informazione.

Per esempio, nella codifica binaria tradizionale dei numeri interi, il numero 0 è
rappresentato dalla sequenza "0", il numero 1 da "1", il numero 2 da "10", il numero
3 da "11", il numero 4 da "100", e così via.

Figura 3. Un indirizzo IP (versione IPv4) e come viene codificato in 4 byte, un byte


per ogni numero, di 8 bit l’uno.

Tutti gli indirizzi IP (versione IPv4) sono definiti mediante l'uso di 4 byte, uno per ogni
numero. Nella codifica binaria usata, ogni byte, ovvero 8 bit, permette di definire un
numero intero da 0 a 255, che sono esattamente i valori che ogni numero
dell'indirizzo IP può assumere. Il procedimento di codifica binaria, ovvero la
rappresentazione di un certo elemento (in questo caso ogni numero di un indirizzo
IP) in formato binario, è mostrato in Figura 3 e funziona come segue.

→Ognuno degli otto bit di un numero facente parte dell’indirizzo IP ha assegnato


uno specifico valore: il valore 1 è associato al bit più a destra, mentre a quello
successivo verso sinistra è assegnato un valore doppio rispetto al precedente (in
questo caso 2), e così via fino ad assegnare un valore numerico ad ognuno degli 8
bit, fino a 128. Questi valori permettono di poter specificare un qualsiasi numero
compreso tra 0 e 255, semplicemente sommandone alcuni fra loro.

Infatti, sommando i soli valori di tutti i bit assegnati a 1 di un certo byte di un indirizzo
IP si riesce a risalire al numero intero dell’indirizzo – ad esempio, il byte 11010000
fa riferimento al numero ottenuto sommando di 128, 64, e 16 (ovvero i valori
assegnati ai bit impostati a 1), che è uguale a 208, il primo numero dell’indirizzo IP
mostrato in Figura 3.

Ovviamente, un qualunque messaggio e/o pacchetto spedito attraverso Internet è di


fatto codificato usando una sequenza di bit.

Una parte di questi bit corrispondono a informazioni relative all’heading del


pacchetto, mentre altre sono relative al payload.

Che cos’è il Transmission Control Protocol (TCP)


L’instradamento basato sul protocollo IP non garantisce che i pacchetti arrivino
nell’ordine corretto in cui il loro payload deve essere poi ricomposto per formare il
messaggio originale →riordino dei pacchetti e lo spezzare il messaggio originale in
più pacchetti conformemente con l’MTU della rete, è gestito dallo strato di trasporto.

Il principale protocollo di questo strato è il Transmission Control Protocol (TCP) che,


insieme al protocollo IP, forma la suite di protocolli Internet, proposti da Vinton Cerf e
Robert Kahn nel maggio del 1974 per essere utilizzati in ARPANET.

→Il TCP permette la consegna affidabile, ordinata, e esente da errori di un


flusso di byte tra due computer in comunicazione tra loro attraverso una rete
basata sul protocollo IP, e gestisce tutti quei processi che garantiscono la
ritrasmissione di un pacchetto nel caso in cui non sia stato recapitato al
destinatario entro un certo tempo limite.

Ogni pacchetto TCP è diviso in due sezioni:

● l’header, che contiene informazioni relative alla comunicazione a livello


trasporto tra i due computer mittente e destinatario
● il payload, ovvero le informazioni che devono essere scambiate tra i
partecipanti alla comunicazione.

In particolare, tra i campi importanti dell’header, ci sono le porte usate dal mittente e
dal destinatario per la comunicazione – quest’ultima può essere specificata nell’URL
della risorsa da ottenere – e un numero di sequenza che indica l'ordine tra i vari
pacchetti in modo da poter ricostruire correttamente il messaggio originale.

Contrariamente al protocollo IP, il protocollo TCP permette di stabilire una


comunicazione connessa, in cui il mittente e il destinatario si mettono d'accordo
di iniziare una comunicazione in modo esplicito prima di scambiarsi i dati, e
dichiarano esplicitamente quando questa comunicazione si può ritenere conclusa.

Il processo di inizio della comunicazione, per esempio, è regolato dal meccanismo


del three-way handshake, mostrato in Figura 5.

Figura 5. Un esempio grafico di three-way


handshake per iniziare una comunicazione con il
protocollo TCP, in cui il mittente e destinatario
si scambiano 3 pacchetti TCP prima di
iniziare a scambiare dati.

Il mittente (nell'esempio dello scenario relativo al


click sul link finora discusso, il computer con il
browser) che vuole iniziare una comunicazione con un destinatario (il server web)
prima invia un pacchetto TCP di sincronizzazione (che verrà incapsulato in un
pacchetto IP dallo strato di rete), con il campo dell'header SYN impostato ad un
numero intero scelto casualmente (il numero "A").

Non appena il destinatario riceve questo pacchetto TCP, risponde al mittente


inviandogli un altro pacchetto con il campo dell’header ACK impostato al numero
successivo rispetto a quello ricevuto (A+1) e con il campo SYN impostato ad un
nuovo numero intero scelto casualmente (B).

Una volta che il mittente riceve questo pacchetto TCP, risponde nuovamente al
destinatario con un nuovo pacchetto, specificando nel campo ACK il numero
successivo a quello appena ricevuto (B+1). Da quel momento, il mittente è
autorizzato a mandare il messaggio, suddiviso in opportuni pacchetti, al destinatario
e, conseguentemente, a ricevere la relativa risposta. Un approccio simile si usa
anche per la chiusura della connessione, ma in questo caso si usa un four-way
handshake, ovvero il mittente e il destinatario si scambiano 4 pacchetti TCP per
terminare la comunicazione.

In pratica, il protocollo TCP implementa quello che normalmente avviene quando


dobbiamo chiamare, per esempio, un qualche centro servizi di un operatore
telefonico per chiedere delle informazioni.

Di solito, prima ci mettiamo d'accordo col sistema (usualmente una voce


pre-registrata) su quale sia il tipo di comunicazione da effettuare (una sorta di
rappresentazione metaforica del three-way handshake), e poi la chiamata viene
effettivamente risposta da un operatore con cui interagiamo direttamente
chiedendogli informazioni (il momento in cui inviamo i dati).

Altri protocolli usati su Internet


HTTP non è il solo protocollo dello stato applicazione largamente usato, ma è
accompagnato da diversi altri che sono usati quotidianamente da molti utenti del
Web → alcuni dei più importanti, totalmente basati sul protocollo TCP per lo strato di
trasporto.

● SMTP. Il Simple Mail Transfer Protocol (SMTP) è il principale protocollo di


comunicazione dello strato applicativo per spedire email. Ogni volta che si
spedisce una mail, in realtà non viene recapitata direttamente al destinatario,
ma viene raccolta da un server di posta di competenza del dominio della
mail del destinatario – dominio identificato dalla parte dell’indirizzo email che
segue il carattere “@”. Questo server è come un server web, ma invece di
gestire il protocollo HTTP e di restituire pagine web, è in grado di ricevere
email attraverso il protocollo SMTP, per poi inoltrarle ai relativi destinatari
quando questi ne fanno richiesta mediante l’uso del protocollo POP o
IMAP

● POP. Il Post Office Protocol (POP) è uno dei due protocolli utilizzato per
ricevere email da un server di posta. In pratica, ogni volta che se ne fa
richiesta, ad esempio attraverso un client per email (Apple Mail, Outlook), il
server di posta consegna tutti i messaggi precedentemente inviati a quel
particolare destinatario e, una volta consegnati, li cancella dal server.

● IMAP. L’Internet Message Access Protocol (IMAP) è l’altro protocollo utilizzato


per ricevere email da un server di posta. È un protocollo più moderno
rispetto a POP, ed è stato esplicitamente sviluppato per facilitare la gestione
di una stessa casella di posta elettronica da parte di più dispositivi. La
differenza principale rispetto a POP è che i messaggi di posta elettronica non
vengono eliminati automaticamente dal server anche se sono stati già
recapitati ai rispettivi destinatari a seguito di una loro richiesta, ma devono
essere eliminati esplicitamente dall’utente, se lo desidera.
● FTP. Il File Transfer Protocol (FTP) è un protocollo che permette il
trasferimento di un qualunque file da un computer ad un server e
viceversa. È uno dei protocolli più adottati di Internet per permettere lo
scaricamento di una grossa mole di dati, mentre è poco adatto per
scaricare documenti molti piccoli, come pagine web.
RIASSUNTO: Cosa succede quando si clicca un link

1) Quando un utente, attraverso il browser sul suo computer collegato a Internet


(e, per questa ragione, identificato da uno specifico indirizzo IP, ad esempio
79.40.124.122), clicca su un collegamento ipertestuale della pagina che sta
navigando, quello che in realtà succede è richiedere delle informazioni
associate ad uno specifico URL in qualche modo incapsulato in quel link – ad
esempio http://es.it/doc1.
2) Il browser interpreta questa richiesta, e prepara un pacchetto HTTP
contenente il messaggio di richiesta, suddiviso in un header contenente
informazioni sulla richiesta e un payload, che in questo specifico caso è
vuoto.
3) A partire dall’informazione relativa all’host (la parte es.it dell’URL), viene
demandato al DNS resolver il compito di recuperare l’indirizzo IP del server
web che dovrebbe contenere informazioni sulla risorsa identificata dall’URL
della richiesta, così da poterla instradare correttamente in rete.
4) Una volta recuperata questa informazione (nell’esempio 130.136.130.1), e
capito (in qualche modo più o meno automatico) quale sia il massimo volume
di dati per pacchetto che la rete può instradare, si iniziano a preparare i vari
pacchetti per la comunicazione.
5) Lo strato di trasporto è responsabile per la creazione dei pacchetti TCP. Una
volta effettuato il three-way handshake per iniziare la comunicazione con il
server web, il messaggio HTTP viene frammentato (se serve) e incapsulato
nel payload di uno o più pacchetti TCP, che specificano nell’header un numero
di sequenza che verrà usato poi dal server web per ricostruire il messaggio
HTTP originale nel caso in cui i frammenti non pervengano nell’ordine
corretto. La dimensione di ogni pacchetto TCP è già conforme alla Maximum
Transmission Unit (MTU) della rete su cui i pacchetti verranno instradati.
6) A questo punto, i pacchetti TCP vengono presi in carica dallo strato di rete,
che li incapsula nuovamente all’interno del payload di altrettanti pacchetti IP,
che nell’header specificano l’indirizzo IP di computer mittente e l’indirizzo IP
del server web destinatario del messaggio, quest’ultimo recuperato in
precedenza grazie al DNS.
7) Fatto ciò, i pacchetti vengono instradati (passando dallo strato di accesso alla
rete) al router più vicino, e successivamente ai vari router presenti in Internet
in modo da poter essere recapitati al server web.
8) Lo strato di rete del server web riceve i pacchetti IP, ne estrae il payload
(ovvero, i relativi pacchetti TCP) e lo passa così com’è allo strato di trasporto.
Lo strato di trasporto interpreta l’header, e in particolare il numero di sequenza
dei pacchetti TCP, in modo da ricostruire correttamente il messaggio HTTP di
richiesta, che viene poi passato allo strato di applicazione.
9) A questo punto, il server web, leggendo le informazioni contenute nell’header
del messaggio HTTP, cerca localmente il documento (nell’esempio, una
pagina web) che corrisponde al percorso richiesto, e specificato nell’URL
iniziale. Una volta trovato, prepara un nuovo messaggio HTTP di risposta che
include, nel payload, una copia della pagina web richiesta.
10)Il messaggio HTTP di risposta viene passato allo strato di trasporto del server
web, che incapsula nuovamente il messaggio HTTP in uno o più pacchetti
TCP della dimensione appropriata per essere trasmessi correttamente in rete.
11) A loro volta, come prima, i pacchetti TCP vengono passati allo strato di rete,
così da incapsularli in altrettanti pacchetti IP, che vengono poi instradati in
Internet, passando dallo strato di accesso alla rete, partendo dal router più
vicino. Ovviamente, la connessione TCP è già attiva, avendo fatto in anticipo il
three-way handshake, e quindi non è necessario ripeterlo. Inoltre, l’indirizzo IP
e la porta su cui effettuare la comunicazione del mittente sono già noti,
essendo stati specificati nei pacchetti IP e TCP della richiesta iniziale.
12)Analogamente a quello che ha fatto il server web, il computer mittente
ricostruisce il messaggio HTTP di risposta, estraendo le informazioni rilevanti
dai vari pacchetti IP e TCP ricevuti.
13)Fatto ciò, il payload del messaggio HTTP di risposta, ovvero la pagina web
richiesta, viene estratta e visualizzata sul browser – e, se serve, vengono fatte
altre richieste HTTP per recuperare informazioni aggiuntive, come le immagini
o i video che di solito non sono contenuti nella pagina web ma sono solo
riferiti tramite i loro URL, come vedremo nel prossimo capitolo.
14)Infine, la comunicazione TCP a livello di trasporto viene chiusa utilizzando il
four-way handshake.

I linguaggi di markup
Un linguaggio di markup (in italiano linguaggio di marcatura o linguaggio di
formattazione) è un insieme di regole che descrivono i meccanismi di
rappresentazione (strutturali, semantici, presentazionali) o impaginazione di un
testo; facendo uso di convenzioni rese standard, tali regole sono utilizzabili su più
supporti. Perciò, la tecnica di formattazione con marcatori (detti espressioni
codificate) richiederà una serie di convenzioni, proprie appunto di un linguaggio a
marcatori di documenti
Marcatura del testo: l’annotazione del testo così da definire esplicitamente i vari ruoli
strutturali e semantici delle varie parti che lo compongono, come l’identificazione
delle sezioni, capoversi, dialoghi, etc.

Esempio tratto dal primo capitolo di Alice’s Adventure in Wonderland:

Alice was beginning to get very tired of sitting by her sister on the bank, and of
having nothing to do: once or twice she had peeped into the book her sister was
reading, but it had no pictures or conversations in it, “and what is the use of a book,”
thought Alice, “without pictures or conversations?” So she was considering in her
own mind, (as well as she could, for the hot day made her feel very sleepy and
stupid,) whether the pleasure of making a daisy-chain would be worth the trouble of
getting up and picking the daisies, when suddenly a white rabbit with pink eyes ran
close by her.

Tutte le strutture che annotano il testo (dialoghi, capoversi, capitoli, etc.), mostrate in
Figura 1, sono organizzate per contenimento, dove la struttura principale, chiamata
book, è descritta da una sorta di scatola che contiene diverse scatole più piccole
chiamate chapter, una per ogni capitolo. Ognuna di queste, a sua volta, contiene
altre scatole chiamate paragraph, una per ogni capoverso, e così via.
L’organizzazione a scatole appena presentata descrive un albero (mostrato in
Figura 2), dove la più grande (ovvero book) altro non è che la radice dell’albero che
contiene i vari chapter, e questi a loro volta contengono i paragraph, e così via.

Figura 1: strutture testuali di base: libro


(book), capitolo (chapter), capoverso
(paragraph), e dialogo (quotation).

Figura 2. L’albero che descrive il


contenimento delle varie strutture
dell’incipit di Alice’s Adventure in
Wonderland.

In modo da definire formalmente la


marcatura relativa a un certo testo,
sono stati sviluppati diversi linguaggi
di markup.

Nel Web seguono una sintassi


specifica introdotta per la prima volta nello Standard Generalized Markup Language
(SGML), rilasciato nel 1986, e poi ripresa dal suo successore, l’Extensible Markup
Language (XML), la cui prima versione è datata 1996.

SGML e XML sono, di fatto, metalinguaggi, ovvero definiscono le regole


sintattiche che devono essere seguite per specificare la marcatura di un testo,
ma non impongono alcun vocabolario particolare per il nome da assegnare ai vari
marcatori – cosa che invece viene poi fatta quando si definisce un linguaggio di
marcatura vero e proprio basato su queste regole sintattiche.
Conformemente alla sintassi di XML, con il termine elemento si denota il nome
informativo che esprime la semantica della porzione del testo al quale
l’elemento si riferisce. Ogni elemento è identificato da due etichette che
delimitano il testo in esso contenuto, chiamati tag.

In particolare, un tag è una sequenza di caratteri che corrisponde al nome


dell’elemento collocato all’interno di parentesi angolari “<” e “>”.

Figura 3: per ogni elemento esistono sempre due tag: il tag di apertura, che
determina dove inizia l’elemento, e quello di chiusura.

Figura 3. I componenti che permettono di definire un elemento di marcatura intorno


ad un blocco di testo.

Tutti gli elementi, nel loro tag di apertura, possono avere specificati degli attributi
nella forma nome_attributo="valore" →Figura 4.

Un attributo contiene delle informazioni aggiuntive associate a quell’elemento


che li specifica. Un elemento può avere nessuno, uno o più attributi.

Figura 4. Come specificare un attributo associato ad un elemento.

Infine, è possibile specificare dei commenti, ovvero delle informazioni opzionali


che possono venire inserite in qualsiasi punto del documento marcato, ma non
fanno parte effettiva del contenuto, sono solo usate per fornire del contenuto
informativo su determinate parti del contenuto.

Grazie ai commenti, specificati Figura 5, si possono inserire informazioni, ad


esempio sui marcatori utilizzati, sulla struttura e organizzazione del documento di
markup.
Figura 5. La sintassi per specificare i commenti in un documento marcato.

Un esempio di documento marcato considerando le regole sintattiche appena


introdotte e partendo da quello mostrato in Figura 1 è il seguente:

<!-- Questo è l’elemento radice, che contiene tutti gli altri -->
<book language="english">
<chapter>
<paragraph>
Alice was beginning to get very tired of sitting by her
sister on the bank, and of having nothing to do: once or
twice she had peeped into the book her sister was reading,
but it had no pictures or conversations in it,
<quotation>“and what is the use of a book,”</quotation>
thought Alice, <quotation>“without pictures or
conversations?”</quotation>
</paragraph>
<paragraph>
So she was considering in her own mind, (as well as she
could, for the hot day made her feel very sleepy and
stupid,) whether the pleasure of making a daisy-chain
would be worth the trouble of getting up and picking the
daisies, when suddenly a white rabbit with pink eyes ran
close by her.
</paragraph>
<!-- Qui ci sono altri paragrafi -->
</chapter>
<chapter> <!-- Il contenuto del secondo capitolo --> </chapter>
<!-- Qui ci sono altri capitoli -->
</book>

Nella scrittura della marcatura di un documento, come in quella precedente, è buona


prassi utilizzare l’indentazione, ovvero l’uso di una sequenza di spazi, per far
rientrare il testo quando ci sono elementi contenuti (o annidati) in altri elementi.
tecnica molto utile → agevola la lettura della marcatura mentre la si sta scrivendo
e quando si devono apportare eventuali modifiche e aggiornamenti.

Hypertext Markup Language (HTML): cenni storici


L’Hypertext Markup Language (HTML) è una delle tecnologie fondamentali del Web,
essendo il linguaggio di markup usato per creare tutte le pagine web e le
applicazioni presenti sul Web.
Nella sua ultima versione, è un linguaggio che segue una sintassi simile a quella
XML (sezione precedente), e che mette a disposizione uno specifico vocabolario di
elementi ed attributi per identificare i vari ruoli strutturali e semantici di una pagina
web.

In pratica, ogni qual volta viene fatta una richiesta per una pagina web, viene
restituita una copia di un documento HTML contenente opportuni marcatori che
il browser è in grado di interpretare e visualizzare a video.

La prima versione di HTML, basata su SGML, è stata creata da Tim Berners-Lee nel
1990 in concomitanza con la creazione del primo browser (WorldWideWeb) , seppur
la prima menzione pubblica del linguaggio avviene solo nel 1991.

Dal 1994, le specifiche delle varie versioni di HTML sono gestite direttamente dal
World Wide Web Consortium (W3C), un’organizzazione internazionale creata da Tim
Berners-Lee volta → gestire l’evoluzione del Web e delle sue tecnologie.

Proprio in quegli anni, HTML inizia ad avere una fortissima diffusione in seguito ai
primi utilizzi commerciali del Web. Negli anni successivi, durante la cosiddetta prima
guerra dei browser tra Netscape e Microsoft, le definizioni di nuove specifiche del
linguaggio HTML si susseguono, rincorrendo le estensioni e le modifiche proposte
dai produttori dei browser che cercano di accaparrarsi quote di mercato.

Negli anni a venire, vengono rilasciate diverse versioni di HTML, fino ad arrivare alla
versione 4.01 del 1999 → miglioramenti apportati ma piuttosto caotica: alcuni
marcatori funzionavano soltanto su alcuni browser o su versioni specifiche di questi,
mentre le indicazioni per gestire gli errori di sintassi erano molto generiche e per
nulla chiare → il W3C decide di iniziare a lavorare ad una nuova versione di HTML
basata interamente sulla sintassi XML, chiamata XHTML, pubblicata ufficialmente
nel 2000 → migliora l'interoperabilità con altri linguaggi basati su XML della stessa
famiglia, come quello per creare immagini vettoriali (Scalable Vector Graphics, o
SVG) e per descrivere formule matematiche (Mathematical Markup Language,
MathML), oltre che a offrire una versione specifica per la telefonia mobile
→sacrificata la piena compatibilità con HTML.

Al termine del W3C Workshop on Web Applications and Compound Documents del
giugno 2004, dopo una accesa discussione si decide per una manciata di voti di non
mantenere la retrocompatibilità con le versioni precedenti nello sviluppo della nuova
versione di XHTML e con HTML stesso.

Sostenitori di HTML, supportati dalle aziende principali produttori di browser in


circolazione (Apple, Mozilla Foundation, Opera Software, e Google), fonda il Web
Hypertext Application Technology Working Group (WHATWG) per proseguire il
lavoro di miglioramento di HTML al di fuori del W3C.
→ sviluppo di una nuova versione di HTML, più orientata allo sviluppo di applicazioni
Web così da rendere le pagine ancora più interattive. La comunità Web, inclusi i
comuni utenti fino alle aziende, preferiscono seguire la linea dettata WHATWG
piuttosto che quella indicata dal W3C, in particolare considerando che i siti web
interamente basati su XHTML erano in larga minoranza.

Il 27 ottobre 2006, Tim Berners-Lee ammette pubblicamente, nel post Reinventing


HTML sul proprio blog, di aver sbagliato nel perseguire in modo così netto lo
sviluppo della nuova versione di XHTML abbandonando completamente HTML, e
annuncia la creazione di un nuovo gruppo di ricerca orientato ad HTML e a quello
che sta facendo il WHATWG. Da quel momento in avanti il W3C e il WHATWG
collaborano fino al 2011, ma continuano ad avere obiettivi inconciliabili:

● W3C vuole cristallizzare e pubblicare la specifica della nuova versione di


HTML5 (quella in uso correntemente nel Web) in un documento ufficiale e
definitivo
● WHATWG non vuole la pubblicazione di una specifica versione ma piuttosto
un living standard in evoluzione continua.

La disputa si conclude con la pubblicazione di entrambi i documenti: il W3C con la


sua Recommendation, e il WHATWG con la sua specifica in costante
aggiornamento.

Elementi HTML principali


Una pagina web è un documento HTML testuale che, attraverso il markup che
specifica, permette la strutturazione del contenuto della pagina, la creazione di link
ipertestuali, e di riferimenti a immagini e/o altri oggetti multimediali. Tutti questi
oggetti marcati vengono interpretati dal browser e visualizzate su schermo in modo
appropriato.

Marcatura o tagging: un’operazione che permette di associare delle etichette, che


definiscono determinati ruoli, alle varie parti del testo.

Per portare un esempio, potremmo immaginare di essere in una cucina con un


blocco di post-it in mano, dove ogni post-it ha una parola scritta sopra, ad esempio
“frigorifero”, “caffè”, “zucchero” etc. → etichettare ciascun oggetto della cucina con il
rispettivo post-it che lo descrive →marcatura.

Scrivere codice HTML equivale a svolgere lo stesso esercizio → si marca, con


opportuni elementi identificati da un tag di chiusura e uno di apertura, il contenuto
testuale di un documento.

Post-it descritti sopra → etichette come “frigorifero” o “mela”, non “frigorifero blu” o
“mela verde” → i post-it servono a descrivere il contenuto dell’oggetto
etichettato, ma non a delinearne le sue caratteristiche esteriori.
Anche gli elementi HTML permettono di descrivere il contenuto della pagina, ma
non danno indicazioni dirette su come questo contenuto deve essere
presentato a video.

Vocabolario degli elementi e degli attributi che si possono usare per marcare un
documento è prestabilito da HTML ed è stato proposto per un uso abbastanza
mnemonico → si usa l’elemento p per identificare un paragrafo, table per identificare
una tabella, title per identificare il titolo della pagina, ecc.

Struttura di base una pagina HTML


Paradossalmente, il primo elemento con il quale inizia un documento HTML non è
un elemento HTML, ma è la Document Type Declaration, che informa il browser su
qual è la versione di HTML che dovrà interpretare.

In particolare, <!DOCTYPE html> è la dichiarazione che indica al browser che il


documento in questione utilizza le regole di marcatura di HTML5.

Il primo elemento, la radice dell’albero, di un documento HTML è html →contiene


tutti gli altri elementi che descrivono la pagina HTML.

Tra i tanti, esiste l’attributo lang, che viene usato per definire la lingua principale
dei contenuti della pagina HTML →il suo valore è il codice della lingua espresso
da due caratteri →“it” (italiano), “en” (inglese), “fr” (francese), e “es” (spagnolo).

Ad esempio, se si vuol indicare che il testo del documento HTML è in italiano, basta
associare il valore “it” all’attributo lang contenuto nel tag di apertura dell’elemento
html: <html lang="it">.

L’elemento html contiene due elementi per distinguere due sezioni importanti della
struttura base di un documento HTML:

● head, le informazioni, tipicamente metadati (come title, il titolo del documento)


utili all’indicizzazione della pagina HTML da parte dei motori di ricerca;
● body, il contenuto vero e proprio del documento (descritto da elementi
come header, nav, h1, article, section, div, p, a, img, video, table, ul, ol, etc.),
che verrà visualizzato dal browser.

Per esempio, le strutture fondamentali che regolano l’organizzazione di un


documento HTML, che contiene l’estratto di Alice’s Adventure in Wonderland di
Lewis Carroll mostrato precedentemente, sono le seguenti:

<!DOCTYPE html>
<html lang="en">
<head>
<title>Alice’s Adventure in Wonderland</title>
</head>
<body>
<!-- il contenuto dell’estratto va qui -->
</body>
</html>

Il testo e la sua marcatura


Il contenuto testuale di un documento HTML può essere organizzato mediante l’uso
di appropriati elementi HTML, che veicolano una precisa semantica.

Titoli

I titoli (heading) vengono usati per organizzare gerarchicamente il contenuto di


un documento HTML →definiti in ordine di importanza, dal più importante al meno
importante: la lettera h (iniziale del termine inglese heading) è seguita da un numero
progressivo da 1 (più importante) a 6 (meno importante), visualizzati dal browser con
dimensioni diverse, così da sottolinearne l’importanza.

Paragrafi
I paragrafi (in inglese paragraph) permettono la suddivisione di un testo.
L’elemento p (iniziale del termine inglese paragraph) permette di definire paragrafi in
HTML. Ad esempio, i due paragrafi dell’estratto di Alice’s Adventures in Wonderland
→ definiti in HTML come segue:

<p>
Alice was beginning to get very tired of sitting by her
sister on the bank, and of having nothing to do: once or
twice she had peeped into the book her sister was reading,
but it had no pictures or conversations in it,
“and what is the use of a book,”
thought Alice, “without pictures or
conversations?”
</p>
<p>
So she was considering in her own mind, (as well as she
could, for the hot day made her feel very sleepy and
stupid,) whether the pleasure of making a daisy-chain
would be worth the trouble of getting up and picking the
daisies, when suddenly a white rabbit with pink eyes ran
close by her.
</p>

Figura 7. Come il browser visualizza i due paragrafi dell’estratto del libro.

Enfasi
Enfatizzare porzioni di testo in HTML si specifica mediante i seguenti due elementi:

● em (abbreviazione del termine inglese emphasized) leggera enfasi,


visualizzata di default in corsivo dal browser;
● strong (abbreviazione dei due termini inglesi strongly emphasized) enfasi
forte, visualizzata di default in grassetto dal browser.

→forte significato semantico per il testo enfatizzato.

Alice was beginning to get <em>very tired</em> of sitting …


… when suddenly a <strong>white rabbit</strong> with pink eyes …

Figura 8. Due enfasi, una normale ed una forte, specificate sulle parole “very tired” e
“white rabbit”.

Citazioni
HTML mette a disposizione tre differenti elementi per specificare le citazioni in un
testo:

● cite descrive il titolo di un lavoro (libro, film, canzone) citato nel testo e, nel
browser, viene tipicamente visualizzato in corsivo;
● q indica una citazione in linea inserita all’interno del paragrafo. Differenti
versioni di browser potrebbero visualizzare la citazione, marcata con
l’elemento q, tra virgolette “…” o sergenti «…»;
● blockquote indica una citazione situata come blocco a sé stante rispetto
al paragrafo. Il browser di default indenta la porzione di testo racchiusa
dall’elemento blockquote →rientro rispetto al resto del testo.

<p>
Riprendiamo nuovamente l’esempio tratto dal primo capitolo
di <cite>Alice’s Adventures in Wonderland</cite> di
Lewis Carroll:
</p>
<blockquote>
<p>
Alice was beginning to get <em>very tired</em> of sitting by
her sister on the bank, and of having nothing to do: once or
twice she had peeped into the book her sister was reading,
but it had no pictures or conversations in it,
<q>and what is the use of a book,</q>
thought Alice, <q>without pictures or
conversations?</q>
</p>
<p>
So she was considering in her own mind, (as well as she
could, for the hot day made her feel very sleepy and
stupid,) whether the pleasure of making a daisy-chain
would be worth the trouble of getting up and picking the
daisies, when suddenly a <strong>white rabbit</strong>
with pink eyes ran close by her.
</p>
</blockquote>

Figura 9. Tutti e tre gli elementi HTML che si riferiscono alle citazioni mostrati come
vengono visualizzati dal browser.
Liste
Una lista permette di organizzare dei frammenti di testo in forma di elenco
ordinato secondo una numerazione oppure non ordinato.

In HTML esistono due elementi che permettono di creare una lista:

● ol per la lista ordinata (acronimo dei termini inglese ordered list);


● ul per la lista non ordinata (acronimo dei termini inglesi unordered list).

Le singole voci della lista, sia ordinata che non ordinata, vengono indicate usando
l’elemento li (acronimo dei termini inglesi list item) →all’interno dell’opportuno
elemento lista che vogliamo usare, devono essere presenti tanti elementi li quanti
sono le voci della lista che vogliamo considerare →gli elementi li possono contenere
ma anche altri elementi HTML.

Il frammento qua sotto mostra due liste, la prima ordinata che rappresenta l’indice
dei capitolo del libro Alice’s Adventures in Wonderland, mentre la seconda non
ordinata elenca i vari personaggi che compaiono nel libro.

<ol>
<li>Nella conigliera</li>
<li>Lo stagno di lagrime</li>
<li>Corsa scompigliata. Racconto con la coda</li>
<li>...<!-- altri capitoli --></li>
</ol>

<ul>

<li>Alice</li>
<li>Coniglio</li>
<li>Gatto del Cheshire</li>
<li>...<!-- altri personaggi --></li>
</ul>

Figura 10. La visualizzazione delle due liste introdotte nel testo sul browser.
Tabelle
In HTML, una tabella (elemento table) è composta da una sequenza di righe
(elemento tr, per table row), ognuna delle quali contiene una o più celle che possono
essere di due tipi:

-celle contenenti dati (td, per table data)

-celle che definiscono intestazioni per le righe o le colonne identificate dalla tabella
(th, per table heading).

Seppur la tabella sia organizzata in righe, ovviamente tutte le celle nella medesima
posizione di ogni riga identificano, in maniera astratta, una particolare colonna della
tabella, come mostrato in Figura 11.

Figura 11. Una tabella e la sua scomposizione in righe, celle, e colonne.

L’esempio di seguito mostra una tabella di quattro righe, in cui la prima ha la


funzione di intestazione, contenente alcuni personaggi del libro e il capitolo dove
appaiono per la prima volta.

<table>
<tr><th>Personaggio</th><th>Capitolo</th></tr>
<tr><td>Alice</td><td>Capitolo 1</td></tr>
<tr><td>Coniglio</td><td>Capitolo 1</td></tr>
<tr><td>Gatto del Cheshire</td><td>Capitolo 6</td></tr>
</table>

Figura 12. Una visualizzazione della tabella in HTML sul browser. I bordi non sono mostrati di default
e, nel caso si vogliano vedere, bisogna specificarlo esplicitamente mediante l’utilizzo dell’attributo
border dell’elemento table (ad esempio <table border="1">).
Collegamenti ipertestuali
I collegamenti ipertestuali (o link) sono il meccanismo utilizzato per creare
l’ipertesto che è sotteso dalle varie pagine Web esistenti. Ogni risorsa sul Web,
sia essa un documento HTML, un’immagine, un video, senza l’esistenza dei link
sarebbe separata dalle altre risorse.

L’intero Web, definendo di fatto un ipertesto, si basa pesantemente sui link,


che possono essere cliccati per “navigare” verso un'altra pagina Web, un’altra
sezione della stessa pagina Web ecc…

Il link definibile in HTML si compone di due parti principali:

● l’etichetta del link: porzione del contenuto cliccabile, solitamente evidenziata


in blu con una sottolineatura, che permette l’identificazione visuale del link sul
browser;
● la destinazione, ovvero l’URL della particolare risorsa che si vuole
“raggiungere” una volta che si è cliccato sull’etichetta.

In HTML, l’elemento per creare un link è a (abbreviazione del termine inglese


anchor, àncora in italiano) accompagnato:

● dall’attributo href (abbreviazione dei due termini inglesi hypertext reference)


che ne definisce la destinazione;
● dal testo (e/o da altri elementi HTML) che contiene, che ne definiscono
l’etichetta.

Ad esempio, il link alla versione di Wikisource del libro definito come segue

Riprendiamo nuovamente l’esempio tratto dal primo capitolo di <a


href="https://en.wikisource.org/wiki/Alice%27s_Adventures_in_Wonderland_(1866)">
<cite>Alice’s Adventure in Wonderland</cite> di Lewis Carroll</a>: …

Figura 13. La visualizzazione di un link ipertestuale sul browser. Se la pagina relativa al link è stata
già visitata, solitamente il link assume il colore viola.

Un link si dice interno alla pagina quando la sua destinazione è un’area dello
stesso documento HTML che lo definisce. In questo caso, per definire l’area
precisa a cui si vuole arrivare a seguito di un click su un link interno, bisogna usare
l’attributo id, con valore una stringa alfabetico a piacere (ad esempio
id="capitolo_1"), sull’elemento HTML su cui si vuole arrivare a seguito del link.
→l’URL della destinazione include soltanto la parte dedicata al frammento, ovvero il
carattere # seguito dalla stringa associata al valore dell’attributo id dell’elemento a
cui si vuole arrivare (ad esempio <a href="capitolo_1">vai al primo capitolo</a>).

Multimedia
Le immagini sono parte importante di un documento HTML. L’elemento HTML per
specificare un’immagine è img, un elemento che non contiene alcun testo ma che
deve specificare i seguenti due attributi:

● src (abbreviazione del termine inglese source), il cui valore indica l’URL dove
reperire il l’immagine;
● alt (abbreviazione dei due termini inglesi alternative text) il cui valore indica
un testo alternativo mostrato al posto dell’immagine se quest’ultima, per
qualsiasi ragione, non è visualizzabile.

→ l’elemento video usato insieme all’elemento source permettono di inserire un


video in un documento HTML. L’elemento source deve avere specificato l’attributo
src che, come per le immagini, si riferisce all’URL dove reperire il video.

Il contenuto di una pagina web


HTML permette di specificare le varie aree logiche di una pagina Web a seconda dei
contenuti che queste contengono →documento può essere suddiviso in diverse
sezioni, come la testata, il piè di pagina, etc.

→possibile modello per l’organizzazione delle varie parti di un documento HTML, in


modo da rendere meglio l’idea di quali sono le varie aree logiche che si possono
utilizzare, e come si potrebbero posizionare.

Figura 14. Un possibile modello per organizzare il


contenuto di una pagina HTML.
Gli elementi in Figura 14 sono:

● l’elemento header contrassegna l’area della testata della pagina e


raggruppa gli elementi introduttivi e di ausilio alla navigazione, ad esempio il
titolo del sito Web, il logo, il menu di navigazione, il campo di ricerca, etc.:
● l’elemento footer individua l’area del “piè di pagina” dove si inseriscono
informazioni sul copyright della pagina, i contatti, l’anno di pubblicazione della
pagina, etc.;
● l’elemento section rappresenta una sezione generica per organizzare,
correlare e contraddistinguere, da un punto di vista tematico, i contenuti. La
sua funzione è simile a quella dei capitoli di un libro o delle sezioni di una tesi
di laurea. Al suo interno puoi avere, ad esempio: articoli, titoli, paragrafi, liste,
tabelle, immagini, video, audio, etc.;
● l’elemento article indica un blocco di contenuto indipendente dal
contesto nel quale si trova, un’entità a sé stante e collocabile anche in
un’altra posizione →insieme di informazioni che abbiano un significato
compiuto e che non necessitano di altri elementi per essere comprese. Il
contenuto del blocco marcato con article può essere l’articolo di una rivista o
di un quotidiano, il post di un blog, o, più in generale, un qualsiasi blocco di
contenuto che sia indipendente e abbia un significato proprio anche se
estratto dal contesto della pagina.
● l’elemento nav individua l’area con i link (o voci) che guidano l’utente
nella navigazione del sito Web;
● l’elemento aside individua l’area i cui contenuti sono in parte in
relazione, arricchiscono o approfondiscono, i contenuti principali, ad
esempio i link di navigazione secondari, i banner pubblicitari, le categorie di
un blog, etc → a lato, per questo è chiamata anche “barra laterale”, ma nulla
vieta di posizionarla in altre aree.

Separazione tra markup e presentazione: i CSS


Nel 1996 rilasciata per la prima volta la specifica del Cascading Style Sheet (CSS),
→ ulteriore linguaggio → definire il livello presentazionale degli elementi di HTML. I
CSS definiscono l’aspetto grafico dei documenti HTML, ad esempio permettendo
di specificare:

● il colore e la dimensione del testo contenuto nei titoli e nei paragrafi;


● la posizione di sezioni, articoli, immagini o video;
● l’animazione dinamica quando si posiziona il cursore del mouse su una voce
del menu e/o sui link;
● etc.

→ permettere la netta separazione tra la struttura del contenuto, definito dagli


elementi del documento HTML, e come questo contenuto deve apparire o essere
visualizzato sul browser, definito dal CSS.
Ogni documento CSS è descritto usando uno specifico linguaggio con una
sintassi completamente diversa da HTML→ CSS permette di definire un insieme
di proprietà presentazionali (colore, font, posizione, ecc.) su determinati elementi
HTML. Ad esempio, per assegnare il colore grigio e l’allineamento giustificato a tutti
gli elementi p (paragraph) della pagina HTML basta definire la seguente regola:

p{
text-align: justify;
color: grey;
}

Nell’esempio, p è il selettore che si riferisce al relativo elemento HTML p. Il blocco


delle regole o dichiarazione di stile associate a quel selettore sono incluse tra
parentesi graffe { }. All’interno delle parentesi si possono indicare una o più coppie
proprietà:valore (separate da dei punti e virgola) che permettono di definire regole di
visualizzazione degli elementi selezionati.

Tecnologie informatiche nelle scienze umane

Al giorno d’oggi, l’uso delle tecnologie informatiche è estremamente pervasivo


→scandisce ogni momento delle nostre attività quotidiane.

→Lo studio delle materie umanistiche non fa eccezione. Il processo di


digitalizzazione di artefatti fisici – come lettere, carteggi, libri, archivi – in documenti
digitali ha reso possibile il loro accesso e studio in modo totalmente remoto, senza
necessariamente recarsi nel luogo dove l’opera viene custodita ma richiedendola in
digitale → esempio archivio di Giovanni Pascoli.

Progetti digitali relativi a studi sulle scienze umane


Tutti i progetti digitali che riguardano le scienze umane hanno delle caratteristiche
comuni:

● ognuno di essi mette a disposizione una piattaforma, solitamente Web, che


permette di usufruire del contenuto digitale del progetto e di presentarlo al
pubblico →scelta in base all’esigenza del progetto
● →strumenti generalisti, come WordPress o MediaWiki (Figura 1), utilizzati
facilmente in diversi contesti.
● strumenti più specialistici, come Omeka S e ResearchSpace (Figura 2), sono
stati sviluppati da studiosi delle scienze umane per scopi molto più specifici e
settoriali, come la pubblicazione di collezioni digitali relative al patrimonio
culturale conservato nei musei o nelle biblioteche.

Figura 1. La pagina principale del concorso Wiki Loves Monuments


Italia, che ha l’obiettivo di raccogliere le fotografie dei monumenti
sparsi sul territorio – che utilizza WordPress come piattaforma di
pubblicazione.
Figura 2. Uno screenshot di alcune risorse
visualizzate attraverso ResearchSpace.

Una volta decisa la piattaforma da usare, un


qualunque progetto di questo genere deve, di
fatto:

● gestire delle risorse digitali come ad es.


un insieme di documenti salvati in uno o più file in un certo formato;
● organizzare queste risorse in modo strutturato e informativo →facilmente
interpretabili non solo dagli esseri umani ma anche da agenti software
intelligenti;
● permettere l’accesso a queste risorse così da fare ricerche e studi specifici su
di esse, ed eventualmente rispondere a determinati quesiti usando le
informazioni a disposizione;
● visualizzare appropriatamente a video le informazioni rilevanti e di rilievo per
una specifica ricerca, così da rendere l’esperienza di navigazione tra le varie
risorse efficace ed efficiente.

Queste caratteristiche sono di fatto comuni in tutte queste tipologie di progetti,


declinati in modo appropriato a seconda della tipologia di risorse digitali gestite e
della piattaforma che meglio si confà alla loro pubblicazione.

Markup ed edizioni digitali


La codifica e l’analisi dei testi → attività principali dell’umanista. Acquisire
competenze sulle tecniche e problematiche della creazione e disseminazione di
documenti elettronici e di archivi digitali testuali → componente caratterizzante
percorsi di studi umanistici

→fondamentale conoscere i meccanismi per rappresentare il testo digitale ed


etichettarne le varie parti con opportuni marcatori → non solo linguaggio di markup
HTML è efficacemente usato per la rappresentazione di testi digitali anche
complessi.

→ Text Encoding Initiative (TEI) è uno dei più famosi linguaggi di markup usati per la
rappresentazione di testi letterari e per la creazioni di edizioni digitali. Negli ultimi
anni, diversi progetti hanno adottato TEI come linguaggio primario per la codifica di
testi antichi in formato digitale → progetto della Bodleian Library di Oxford in figura 3.

Figura 3. Un estratto dalla versione digitale del First


Folio di Shakespeare, relativa all’incipit del Sogno di
una Notte di Mezza Estate.

TEI viene anche usato per alcune delle principali


attività della filologia, come la ricostruzione della
forma originaria di un testo attraverso l’analisi delle fonti che lo testimoniano, o la
creazione di edizioni critiche, dove si mettono a confronto due varianti dello stesso
testo.

attività di marcatura supportata da strumenti visuali per la creazione della versione


digitale delle varianti in considerazione → efficace ed efficiente per un’analisi
qualitativa di queste varianti; cfr. figura 4

Figura 4. Uno screenshot di PhiloEditor, che


visualizza le differenze tra due versioni del
secondo capitolo de I Promessi Sposi di
Alessandro Manzoni, rispettivamente quella del
1827 e quella del 1840.

Collezioni di dati
“dato” dal latino “datum” che significa “cosa
data” →definizione formale: una frase
dichiarativa soggetto-predicato-oggetto che
attribuisce ad una entità (il soggetto),
attraverso il predicato, un valore o la mette in relazione con un’altra entità (l’oggetto).

dati rappresentati in svariate forme → la più comune è quella tabellare, tipica dei
programmi come Excel. Nel caso delle tabelle, ogni riga contiene dati su una certa
entità, mentre ogni singola cella, definisce un dato.

per esempio dati in Tabella 1 → ogni riga della tabella, eccetto la prima che ha la
funzione di intestazione, definisce un musicista → il musicista definito nella prima
riga (il nostro soggetto) ha come nome “John” (il primo dato), come cognome
“Lennon” (il secondo dato), e come genere “maschio” (il terzo dato). Seguendo
l’approccio soggetto-predicato-oggetto possiamo definire questi tre dati anche come
segue:

1. il musicista identificato dalla prima riga (soggetto) ha nome (predicato) John


(oggetto);
2. il musicista identificato dalla prima riga (soggetto) ha cognome (predicato)
Lennon (oggetto);
3. il musicista identificato dalla prima riga (soggetto) ha genere (predicato)
maschio (oggetto).

Nome Cognome Genere

John Lennon maschio


Janis Joplin femmina

Fredd Mercury maschio


y

Tabella 1. Una tabella contenenti dati su alcuni musicisti. Ogni riga rappresenta un
cantante mentre ogni cella esprime un dato su quel cantante.

Quando si ha un grande insieme di dati in forma tabellare o in qualche altro modo, è


possibile organizzarli all’interno di una base di dati → una collezione di dati
organizzati secondo determinati criteri che ne abilita l’accesso mediante opportuni
linguaggi di interrogazione che permettono, per esempio, di restituire dati che
forniscono risposte a domande come “quali sono i musicisti maschi che si chiamano
John?”.

→strumenti abbastanza pervasivi non solo nel contesto di domini nativamente


digitali, ma anche nelle scienze umanistiche. I dati relativi ai libri posseduti da una
biblioteca, interrogabili attraverso un computer, così come la descrizione di oggetti
museali messi a disposizione su un sito Web →contenuti in opportune basi di dati
→facilitarne lo studio.

Esempio: progetto Zeri & LODE → significativa base di dati, collegati tra loro e con
entità esterne contenute in altre basi di dati, come Wikidata e GeoNames, su
fotografie di opere d’arte relative alla pittura italiana del XVI secolo collezionate nel
tempo dal famoso critico d’arte Federico Zeri e conservate dalla Fondazione
Federico Zeri dell’Università di Bologna.

Altro esempio rilevante in questo settore è il progetto ArCo, Architettura della


Conoscenza, dalla collaborazione con il Centro Nazionale delle Ricerche (CNR) e
l’Istituto Centrale per il Catalogo e la Documentazione (ICCD) → tale progetto ha
pubblicato svariati modelli concettuali per la descrizione dei dati relativi a beni
culturali materiali e immateriali con relative schede catalografiche, gli eventi che
coinvolgono i beni culturali, e loro localizzazione geografica e amministrativa, e sia
larghe collezioni di dati su questi beni culturali in Italia.

Conclusioni
→panoramica dell’utilizzo delle tecnologie informatiche per studi e ricerche attinenti
alle scienze umane → esempi concreti di applicazioni e progetti sviluppati →
impossibile non considerare le tecnologie informatiche nell’approccio allo studio di
materie e argomenti prettamente umanistici → l’informatica e il pensiero
computazionale non devono essere visti come oggetti ostili, ma piuttosto come
strumenti non solo utili ma fondamentali per uno studio completo, appropriato ed
efficace delle discipline umanistiche.

Potrebbero piacerti anche