Domanda Astrazione funzionale o Astrazione procedurale? Sono la stessa cosa? E potete darmi qualche chiarimento sull'argomento?

giovy2707

Utente Electrum
27 Giugno 2019
96
38
62
103
Premetto che conosco il concetto di astrazione, e che so programmare in C, il dubbio è solo di tipo teorico, il mio dubbio è nato da del materiale che ci hanno fornito all'università che (in contrapposizione con quanto detto durante il corso di programmazione 1) chiamava l'astrazione funzionale, "astrazione procedurale", ora dal momento che funzione e procedura sono cose diverse non vorrei essermi perso qualche concetto teorico. Poi leggendo in giro per il web ho letto definizioni discordanti sul concetto di "astrazione funzionale", io ho sempre saputo che questa tecnica consistesse nel suddividere un problema in sotto-problemi (tecnica top-down) e risolvere ogni sotto-problema attraverso delle funzioni (all'interno del codice)
 
Il paradigma procedurale è quello che conosci dal C. Il codice sorgente è diviso in blocchi (chiamati procedure, funzioni o subroutine) che implementano una certa funzionalità. Le differenza tra procedura e funzione è praticamente inesistente, infatti la maggior parte dei linguaggi non fa alcuna distinzione sintattica tra le due cose. Le procedure sono semplicemente delle funzioni senza parametri. Il paradigma funzionale è una cosa completamente diversa, anche perché invece di essere imperativo (come il paradigma procedurale e quello object-oriented) è dichiarativo.

Nel paradigma funzionale il concetto di funzione deriva dalle funzioni in matematica: una funzione è la descrizione di un output, dato un certo input. Se una funzione chiamata con con in input "Pippo" deve restituire "Hello Pippo!", ogni volta che la chiami con in input "Pippo" otterrai "Hello Pippo!". Fin qui non sembra niente di strano, ma c'è una differenza fondamentale rispetto alle funzioni del C: come faccio a scrivere una funzione che prende in input "pippo.txt" e mi restituisce in output il contenuto del file pippo.txt? Abbiamo due problemi: 1) il contenuto del file dipende dal tuo computer; e 2) il file potrebbe non esistere. Apparentemente, non possiamo scrivere una funzione (ie., dato un input avere sempre lo stesso output) per leggere files, né per leggere l'input dell'utente, o per interagire con la rete. Non possiamo farlo perché l'output di queste funzioni dipende da agenti esterni. Questi problemi si risolvono usando delle astrazioni matematiche (eg., la monade) che ti permettono di modellare anche questi scenari; oppure, più semplicemente, introducendo delle impurità nel linguaggio.
Oltre a questa differenza, un altra differenza colossale rispetto al paradigma procedurale è che nel paradgma funzionale tutto è una costante: se hai una variabile x che vale 7, non puoi fare x++ per farla valere 8. Le variabili di fatto sono solo dei nomi legati (infatti si chiamano "binding" e non "variabili") a delle cose. Rinunciare alle variabili significa che non può esistere il ciclo for, perché non puoi creare una variabile che cambia di valore, e non esiste nemmeno il ciclo while, perché il predicato sarebbe o sempre vero (loop infinito) o sempre falso. Queste problematiche si risolvono con un uso massiccio delle funzioni ricorsive.
Se ne potrebbe parlare di più, ma queste sono le caratteristiche principali che mi sento di introdurti in questo post. (se hai qualche curiosità, chiedi pure).

La maggior parte dei linguaggi sono di fatto multiparadigma, perché ti permettono di seguire approcci diversi per risolvere un dato problema, ma di fatto i programmi scritti usando linguaggi puri tendono ad essere anche molto più chiari e puliti e molto meno bug-prone. Quelle che io ti ho elencato come limitazioni, in realtà da un certo punto di vista sono dei vantaggi. La programmazione funzionale è tornata in auge (è nata negli anni '50, ma fino al 2005 non se la filava quasi nessuno) anche perché quelle che io ti ho elencato come limitazioni rendono di fatto impossibile avere problemi di data-race. Se hai scritto un programma utilizzando un linguaggio di programmazione purely functional non avrai alcuna difficoltà a fargli sfruttare tutti i core della tua CPU, cosa che in C è molto difficile.