Il codice binario e i bit: come l'astratto divenne concreto

Nell'ambito della filosofia dell'informatica spicca il nome di Aden Evens per la sua importante opera: Logic of the digital.

Il libro è diviso in diversi capitoli, ognuno dedicato ad un tema specifico o un livello di astrazione del computer.

Aden Evens
Aden Evens

I capitoli da un lato offrono una spiegazione passo a passo sul funzionamento di un computer, dall'altro riescono a estrarre problematiche filosofiche concernenti i temi trattati.

Da questo punto di vista, anche se il libro non è particolarmente voluminoso, certamente è molto ricco. Esso sembra quasi preannunciare un nuovo approccio della filosofia verso l'informatica.

Il testo di Evens incomincia con il tema dei bit.

Il termine "bit" rimanda a "binary digit" e indica quella lista di 1 e di 0 che stanno alla base del funzionamento di tutto il computer.

1 significa passaggio della correte,

0 significa l'assenza del passaggio della corrente.

Questi numeri sono dei valori esclusivi, può darsi uno a patto che non si dia l'altro.

L'essere 1 è il non essere 0 e vice versa. Ovviamente 1 e 0 possono essere anche visti come sì o no, vero o falso, ecc.

Le scelte fondamentali della vita, come si vede nella prima serie di Mr. Robot, seguono un codice binario: o questo o quello.

C'è persino chi ha pensato che l'interno universo sia fatto di bit. Questa tesi è ben nota ed è stata sostenuta dal famoso fisico: John Archibald Wheeler.

Ad ogni modo, in informatica il codice binario è la base, ma è anche qualcosa che troviamo ovunque.

Mano a mano nel libro Evens spiega come il codice binario si ripete nel computer su tutti i livelli.

Un esempio semplice è il mouse: o clicchi (1) o non clicchi (0).

Un bit, spiega Evens, può rappresentare tante cose:

un pixel di uno sfondo arancione di un'immagine, un dato sul genere di una persona (maschio o femmina), ecc.

Dunque il bit è presente ovunque nel computer, ma dal punto di vista materiale, dice Evens, occupa una piccola area nella superficie di un hardware.

Una delle caratteristiche essenziali dei bit è il loro carattere astratto.

I bit sono astratti nella misura in cui possono astrarre dal materiale e dal potenziale elettrico. Con questo intendo dire che i bit si adattano a materiali molto diversi.

Con il digitale possiamo arrivare agli stessi risultati cambiando i materiali, anche se certamente non avremo lo stesso tipo di prestazioni.

Inoltre, afferma Evens, anche se si scelgono due valori di potenziali elettrici per rappresentare 1 e 0, ad esempio + 2 e +5 volts, questi valori sono idealizzazioni, in quanto i bit trattano come omogenei valori approssimativi a +2 e +5 volts.

Il bit, in questa lettura di Evens, risulta come una specie di tecnologia dell'astrazione, un'astrazione che sostituisce alle differenze valori omogenei.

Se prendiamo il bit come semplice codice binario ci troviamo di fronte a due sole opzioni:

sì/no, on/off, vero/falso, ecc.

Tuttavia, nell'informatica i bit sono presi in sequenze.

Una serie di 8 bit, ad esempio, costituisce un byte. Un Kilobyte è mille bytes, un Megabyte è un milione di bytes, un Gigabyte è un bilione di bytes e un Terabyte è un trilione di bytes.

Prendiamo una canzone in mp3 a caso, ad esempio "The last fight" dei Bullet for my valentine. Essa occupa sul computer 10,4 Megabytes, ossia corrisponde a 10,4 milioni di bytes, dunque 83,2 milioni di bit.

È difficile pensarlo, date le dimensioni fisiche dell'hardware, ma è così.

Quindi, spiega Evens, se 1 e 0 stanno per due stati possibili, una lista di 1 e di 0 sta per 2^n stati possibili. Con n = 2 si ottengono quattro stati: 00, 01, 10, 11.

Grazie all'aritmetica binaria, studiata principalmente da Leibniz, è possibile rappresentare ogni numero come una sequenza di 1 e di 0.

Ad esempio i primi dieci numeri saranno scritti in numeri binari in questo modo:
numero decimale:
0
1
2
3
4
5
6
7
8
9
10
numero binario:
0
1
10
11
100
101
111
1000
1001
1010

I bit sono, afferma Evens, "l'apoteosi dell'astrazione".

Foto per Il codice binario e i bit
foto per Il codice binario e i bit

L'efficienza, la velocità, la riproduzione, la comunicazione nei bit dipendono tutti dalla capacità di astrazione. Il bit è l'unità minima di informazione, esso richiede una base materiale, ma nel significato è completamente disgiunto da essa.

L'unico vero significato di un bit è che non è l'altro, così 1 vuol dire che non è 0 e vice versa.

Secondo Evens i bit potrebbero non appartenere nemmeno al reame dei segni, se per segni si intende quel che intendeva Peirce:

una qualcosa che sta per qualcos'altro.

Un bit può codificare una lettera, ma non avrà nessuna relazione con la lettera che codifica.

Ogni carattere del computer corrisponde ad un numero e questo numero corrisponde, trasformato in numero binario, ad una sequenza di bit.

Lo standard ASCII, spiega Evens, associa i valori da 0 a 127 con le lettere maiuscole e minuscole dell'alfabeto inglese. ASCII è un sistema di codificazione che assegna ad una serie di bit un simbolo o un carattere.

Ecco tre esempi di codificazione ASCII:

1) ! = 33 = 010 0001
2) f = 66 = 110 0110
3) G = 47 = 100 0111

Ogni carattere o simbolo corrisponde ad un numero, il quale a sua volta corrisponde ad una serie di bit. Tuttavia, come nota Evens, non c'è nessuna relazione, se non di convenzione, tra "f" e "110 0110".

I bit sono materializzati al minimo di modo da ridurre il più possibile la resistenza del materiale e sono fatti per usare il minor volume di energia in poco spazio.

Separati dalla materialità i bit operano in un mondo isolato, puramente formale, distinto dalla contingenza della materia, un mondo di pura necessità. Con la rottura della base materiale del bit il computer smette di funzionare o si rompe.

Il digitale, osserva Evens, o funziona o si rompe, non ci sono vie di mezzo. Il bit indica come l'astratto è diventato concreto, come l'astrazione può avere effetti e diventare motore del digitale.

Inoltre il bit traduce ogni informazione in codice binario:

il genere corrisponde ad un 1 o uno 0, il paese di provenienza è un numero e il numero decimale corrisponde ad uno binario, quindi ad una sequenza di bit, ecc.

Abbiamo visto come funzionano questi bit e sappiamo che ruolo svolgono all'interno dell'hardware, ma precisamente quali sono le componenti di base di un computer?

Nel computer troviamo:

1) Il case: è l'involucro esterno ed è ciò che contiene tutte le restanti componenti. Il case è caratterizzato da dei canali di areazione per permettere il flusso d'aria. Esso in particolare è dotato di alcune ventole disposte a questo scopo. Inoltre nel case troviamo le porte USB con le quali colleghiamo mouse, tastiera, penne USB e altri dispositivi al computer.

2) Scheda madre: è la scheda elettronica principale, un circuito stampato. Essa è composta da tante parti tra cui:

a) Il Socket: il luogo dove viene riposto il processore (CPU).
b) La ROM: è la memoria a sola lettura. Non può essere modificata o cancellata e contiene dati necessari per l'avvio del computer. A differenza della RAM i dati sono salvati, anche quando il computer viene spento.
c) I Chipset: i circuiti integrati che smistano le informazioni sulla scheda madre.
d) Connettori: un connettore per l'alimentatore e i connettori IDE.

3) Processore: la CPU o unità di elaborazione centrale. È il pezzo da inserire nel Socket. La CPU esegue le istruzioni di un programma richieste dal sistema operativo e dal software. Esso deve poter leggere e scrivere i dati della RAM. Inoltre deve riconoscere ed eseguire i comandi forniti dai programmi. Le CPU sono costituite da diversi core. Un esempio di processore sono gli Intel core.

4) La RAM: è la memoria ad accesso sequenziale. È solo una memoria momentanea, non salva permanentemente i dati. Essa semplicemente copia i programmi che esegue il processore. Quando si spegne il computer tutti i dati della RAM sono persi.

5) Dissipatori: dispositivi disposti sopra la CPU per abbassare la temperatura del processore. Questi dispositivi sono principalmente composti da una o più ventole.

6) Scheda video: è una scheda elettronica che elabora il segnale video. In pratica, grazie alla scheda video vediamo l'interfaccia del computer nel monitor.

7) Hard disk: è il disco rigido, ossia una memoria magnetica dove sono immagazzinati i dati. In parole semplici è dove sono salvati tutti i file del computer. Il computer ne ha uno interno, ma si possono collegare al computer hard disk esterni per espandere la memoria.

8) Alimentatore: l'alimentatore è quella tecnologia che permette di passare energia elettrica al computer.

9) Periferiche input-output: il complesso composto da tastiera, mouse, monitor, casse, ecc.

Con tutti questi elementi dovremmo avere una visione complessiva del computer e delle sue componenti.

Ho detto che i bit operano sul piano hardware.

L'Hardware, rispetto a tutte queste componenti, non è una singola di esse, ma un complesso composto dalla maggior parte di esse. L'hardware è la CPU, la RAM, l'Hard disk, ecc.

L'Hardware, dunque, rappresenta le componenti fisiche del sistema, mentre il software è quell'insieme di programmi eseguiti dal sistema.

I software si dividono in due: quelli di base o sistemi operativi (Windows, Mac, Unix, Linux); quelli applicativi (Word, Excel, ecc.). Gli applicativi servono per realizzare operazioni specifiche e presuppongono il sistema operativo.

I bit della RAM e quelli dell'hard disk corrispondono con i dati che vediamo nell'interfaccia, ma la maggior parte dei bit non si vedono e non hanno nulla a che vedere con quello che osserviamo nell'interfaccia o sul display.

Per quanto riguarda l'interfaccia vediamo diversi elementi come i caratteri, i colori dei pixel, ecc.

Ogni pixel corrisponde ad un valore numerico.

Per ottenere i vari colori esistono vari metodi, uno di questi è l'RGB (red, green, blue). Questo metodo mescola i colori rosso, blu e verde.

Per quanto riguarda i caratteri, come ho spiegato precedentemente, esistono dei metodi come ASCII che assegnano ad ogni carattere sequenze specifiche di bit. In questo modo si realizzano tutti quei caratteri vediamo in programmi come Word o LibreOffice.

Tuttavia questi caratteri possono modificati, si può scrivere in grassetto, in corsivo, scrivere giustificato, con un certa grandezza, con un certo colore, ecc. Tutto questo aggiunge altri codici numerici a quelli già esistenti, ossia ai codici dei caratteri.

Queste tecniche sono dette tecniche di markup. Un esempio noto è il caso di HTML o l'hypertext markup language, usato nel web per realizzare tutta la parte di testo.

Se metto in grassetto una parola, questo almeno si vede nell'interfaccia, ma ci sono ancora moltissimi codici che non appaiono mai nell'interfaccia sotto forma di elementi visibili, ma sono essenziali perché fanno funzionare tutto il resto. Tutti quei codici che servono per la trasmissione, immagazzinamento e alterazione degli oggetti nell'interfaccia o altrove.

In generale esistono due tipi di linguaggi di programmazione:

quelli di alto livello e quelli di basso livello.

I linguaggi di basso livello sono meno distanti dall'hardware, quelli di alto livello lo sono molto di più. Quando facciamo programmazione di solito abbiamo bisogno principalmente di due cose: uno strumento per compilare il codice e uno strumento che lo esegua.

Per scrivere il codice basta usare un semplice editor di testo. L'editor di testo spesso lo si trova già sul computer e non c'è bisogno di scaricare nulla. Esempi di editor di testo sono i seguenti: Notepad ++, Brackets, Eclipse, Bluefish, Gedit, Dreamweaver, Visual Studio.

Il codice che viene scritto sull'editor viene tradotto successivamente da un compilatore in codice oggetto. Il tempo dell'informatica è diviso in due: compile-time e run-time.

Il "compile-time" o tempo di compilazione è il tempo in cui lavora il programmatore.

Il "run-time" o tempo di esecuzione è il tempo che si riferisce al codice già compilato che viene eseguito.

La compilazione consiste nella traduzione in termini binari del codice sorgente che viene scritto con l'editor.

Queste informazioni Evens le riferisce a linguaggio di alto livello, ma non parte dell'interpretazione, che è un metodo alternativo alla compilazione ed è usato da molti linguaggi di programmazione.

Il metodo della compilazione è usato in linguaggi come C, Java e Python, ma in altri linguaggi come Javascript, Perl, PHP, si usa il metodo dell’interpretazione. Ogni istruzione viene interpretata ed eseguita da un interprete. Quando scrivo uno script in Javascript, ad esempio, uso un editor di testo per scrivere il codice sorgente e in seguito faccio eseguire questo stesso codice dal browser.

Aden Evens definisce i linguaggi di programmazione come macchine virtuali eseguite in macchine attuali.

Evens nel primo capitolo analizza un tipo particolare di programmi: i linguaggi di programmazione procedurali, ossia i linguaggi che funzionano per procedure. Per capire bene come funziona un linguaggio di programmazione è meglio presentare gli elementi di base di un linguaggio di programmazione.

Esistono moltissimi linguaggi, io prenderò come esempio uno molto semplice: PHP.

In primo luogo nella programmazione dobbiamo tenere conto dei tipi differenti di dati che andiamo ad inserire.

Prima di vedere i dati, se scrivete in Php, sappiate che tutto il codice va scritto qui dentro:
<?php
?>
Il codice deve comparire dopo '<?php'.

Nella maggior parte dei linguaggi esistono questi tipi di dati:

stringhe : 'Ciao, sono Myke', 'Come stai?', ecc.
numeri: 1, 2, 3, 4, ecc.
booleani: true, false.

In Php, come in altri linguaggi, esistono dei metodi per fare comparire il dato così come è scritto:

echo 'Mi chiamo Davide';
print('Mi chiamo Davide'); (un metodo simile esiste anche in Python)

Nella maggior parte dei linguaggi, per non ripetere sempre i dati si usano delle variabili, in Php si scrivono in questo modo:

$name = 'Davide';
$name è variabile, mentre 'Davide' è il valore della variabile. In altri linguaggi le variabili si scrivono in maniera diversa, ad esempio:
in Javascript: var name = 'Davide';
in Python: name = 'Davide';

È possibile usare delle variabili per inserire molti più dati. Per questo si usano quelli che vengono chiamati 'array'. Un array in Php si scrive in questo modo:
$girls = array('Noemi','Alessandra', 'Fabrizia', 'Claudia');
var_dump($girls);

L'array si scrive quasi come le variabili, ma al di là dell'uguale si inserisce array() e nella parentesi si scrivono tutti i dati. La funzione 'var_dump', tipica di Php, ci permette di conoscere tutti gli elementi dell'array numerati. Gli elementi dell'array sono numerati dallo 0, dunque sono nel nostro caso:

array(4) { [0]=> string(5) "Noemi" [1]=> string(10) "Alessandra" [2]=> string(8) "Fabrizia" [3]=> string(7) "Claudia" }

Quattro elementi nell'array, ogni elemento è numerato e ogni elemento ha il numero di lettere contate. In altri linguaggi si scrive in modo diverso, ad esempio:

in Javascript: var girls = new Array('Noemi','Alessandra', 'Fabrizia', 'Claudia');
in Python: girls = ['Noemi','Alessandra', 'Fabrizia', 'Claudia'];

Una volta compreso cosa sono variabili e gli array è possibile usare le variabili all'interno di procedure specifiche.

Un primo esempio di procedura sono gli if. In Php un if è strutturato in questo modo:
$number1 = 33;
$number2 = 67;
if($number1<$number2 OR $number1=$number2) {
echo 'True!';
} else {
echo 'False';
}

Prima ho dichiarato due variabili ($number1 e $number2), assegnando loro dei valori numerici. Poi ho inserito una procedura if.

Questa procedura, cosa curiosa, funziona esattamente come con il condizionale in logica, quando dico: se domani nevica, non prederò la macchina. L'if ha delle condizioni tra le parentesi tonde, in questo caso: $number1<$number2 OR $number1=$number2.

L'enunciato delle condizioni dice questo: o 33 è minore di 67, oppure 33 è uguale a 67. Se questa condizione è vera, allora deve essere eseguito il codice tra le parentesi graffe. Else, invece, è la procedura da eseguire nel caso in cui la condizione nell'if non risulti vera. In questo caso compare sul mio browser la scritta 'True', in quanto sono vere le condizioni. Se fate la tabella della verità di quella disgiunzione o OR booleano, che ho scritto come condizione nell'if, allora otterrete che 1 + 0 = 1.

Dopo gli if vengono le funzioni.

Esistono due tipi di funzioni: le funzioni possono essere già definite, oppure possiamo crearle noi stessi.

Ecco un esempio di funzione definita in Php:
$name = 'Daniele';
echo strlen($name);
strlen() serve per calcolare la lunghezza di una stringa. In questo caso la parola Daniele è una stringa di sette lettere, dunque il computer scrive 7.

Una funzione creata si scrive in Php in questo modo:

function Scrivi() {
echo 'Questo è il messaggio';
}
Scrivi();

Questa funzione è molto semplice. Gli ho assegnato un nome(Scrivi), ho messo un messaggio da scrivere e ho chiuso il codice richiamandomi alla funzione: Scrivi();. Anche qui si possono scrivere condizioni tra le parentesi tonde e si inserire un codice da eseguire tra le parentesi graffe.

Vediamo ora come funzionano i loop.

Ho scritto in un testo precedente che un loop si ha quando il computer continua ad eseguire ripetutamente una istruzione. I loop infiniti sono uno di quei casi disgraziati in cui nessuno vorrebbe incappare, altrimenti il computer va in tilt. Bisogna dunque assicurarsi, quando si scrive un loop, che il loop sia finito e dunque che noi abbiamo dichiarato dei limiti. Esistono tre tipi di loop: while, do-while, for. Vediamo come funzionano in Php:

While:
$number1 = 1;
while($number1<=10) {
echo $number1.'<br />';
$number1++;
}

Do-While:
$number1 = 1;
do {
echo $number1.'<br />';
$number1++;
}
while($number1<=10)

For:
for($number1 = 1; $number1<=10; $number1++) {
echo $number1.'<br/>';
}

In tutti questi casi il risultato è il seguente: una lista di numeri da 1 a 10. Quello che cambia, al di là del nome dell'istruzione da eseguire, è il modo in cui sono disposte le tre condizioni. Una condizione definisce la variabile ($number1 = 1), un'altra serve per dare un limite al loop ($number1<=10), l'ultima dice che il valore della variabile deve incrementare di uno ogni volta ($number1++).

L'ultimo elemento importante è lo switch.

In Php uno switch si scrive in questo modo:
$giorno = 'Lunedì';
switch($giorno) {
case Lunedì:
echo 'Andare in palestra';
break;
case Martedì:
echo 'Andare in ufficio';
break;
case Mercoledì:
echo 'Andare in pizzeria';
break;
case Lunedì:
echo 'Andare a casa di Claudia';
break;
case Giovedì:
echo 'Studiare C++';
break;
case Venerdì:
echo 'Dormire';
break;
case Sabato:
echo 'Scrivere';
break;
case Domenica:
echo 'Andare in gita';
break;
}

Si mette una variabile, questa variabile diventa la condizione dello switch. Nello switch compaiono una serie di casi. Ho inserito una serie di attività per ogni giorno della settimana.

In questo caso comparirà l'attività corrispondente al caso che coincide con il valore della variabile.

Nell'ultima parte del primo capitolo Evens tratta ancora del tema dello 'scoping'.

È una pratica che si usa con le variabili. Esistono due tipi di 'scope': global scope; local scope. Se una variabile è dichiarata dentro una funzione, un if o simili, allora è locale, dunque è local scope. Se, al contrario, la variabile è dichiarata esternamente è global scopre.

Global scope:
$number = 1
if($number < 2) {
echo 'Questo è vero';
}
Local scope:
if($number < 2) {
echo 'Questo è vero';
$number = 1;
return;
}
Abbiamo visto come i grandi numeri della logica filosofica (1 e 0) governano l'intera informatica e siano ovunque all'interno del computer.

Chi lo avrebbe detto che l'astrazione è in grado di avere effetti concreti?

Di solito si dice che la logica filosofica è troppo teorica o astratta e che non trova applicazioni pratiche.

La tecnofilosofia tratta tutte le tecnologie che si basano sul codice binario e gli operatori boolenani come tecnologie basate sulla logica.

Il punto è questo: la logica è un campo molto più amplio di quello che ho definito qui, quanti altri ambiti della logica potrebbero tradursi in tecnologia?