Come risultato di commentare la discussione qui , mi chiedo se è possibile imparare la programmazione funzionale in C?
Come risultato di commentare la discussione qui , mi chiedo se è possibile imparare la programmazione funzionale in C?
Ovviamente puoi fare programmazione funzionale in C. In teoria, puoi anche imparare principi di programmazione funzionale in C, ma il linguaggio non lo rende facile.
Suppongo che tu abbia almeno un po 'di esperienza in OOP; se lo fai, dovresti sapere che l'OOP può essere fatto in C, incluso polimorfismo, getter / setter, regole di visibilità, ecc. ecc., ma è piuttosto doloroso farlo, e devi conoscere sia l'OOP che il C all'interno - fuori per tirarlo fuori. È praticamente la stessa cosa con FP.
Quello che dovrebbe fare è prima imparare un linguaggio di programmazione funzionale (molti di essi hanno regole di sintassi sorprendentemente semplici, non è la sintassi che li rende difficili da imparare), e allora lascia che la saggezza acquisita da poco influenzi il modo in cui scrivi C
Come da richiesta, alcune cose che puoi imparare da FP e quindi applicare in, per esempio, C, C ++ o Java:
C può essere violato per offrire alcuni concetti funzionali:
Questa domanda StackOverflow ti dirà di più . Ma anche se sembra possibile fare una programmazione funzionale (o un grosso sottoinsieme di) in C, hack e estensioni del compilatore e qualunque cosa non sia il modo migliore per imparare un concetto.
In realtà impara programmazione funzionale la tua migliore scommessa è uno dei principali linguaggi di programmazione funzionale come Lisp e i suoi dialetti ( Clojure , Schema ), Erlang e Haskell . Ognuno di questi sono strumenti perfetti che funzionano all'interno della mentalità di programmazione funzionale. F # è anche un buon candidato se hai uno sfondo .Net, ma è un linguaggio multi-paradigma, non strettamente un linguaggio di programmazione funzionale.
Come note tdammers nei commenti:
Actually, LISP, clojure and scheme are also multi-paradigm; Haskell, while being pure and default-lazy, also allows for imperative programming while in a monadic context, and it has extensive support for concurrent processing. All of these have mechanisms that implement large parts of the wisdom gathered in the OOP world - encapsulation, inheritance, single-responsibility, composition, etc. It's not so much about whether a language ALLOWS other paradigms; it's about which paradigm forms a language's starting point.
Per quanto ne so, Lisp ei suoi dialetti e Erlang sono candidati migliori di F # perché incoraggiano la programmazione funzionale rispetto ad altri paradigmi, cosa tdammers afferma splendidamente come il punto di partenza di una lingua . F # comprende la programmazione funzionale ma non la incoraggia rispetto ai suoi altri paradigmi supportati, programmazione imperativa e oo.
Non puoi imparare tutti gli aspetti della programmazione funzionale in C. Ma sicuramente puoi iniziare la programmazione in stile funzionale con qualsiasi linguaggio imperativo. Questi bit di partenza sono- "Come mantenere le cose pure durante la programmazione." E può essere fatto anche C Controlla questo post del blog per i dettagli -
La programmazione funzionale riguarda le chiusure e le loro applicazioni. A meno che qualcuno non sia in grado di mostrarti una libreria di chiusura di discesa per C, dimentica di usare C per apprendere la programmazione funzionale.
Il concetto cardinale di programmazione funzionale è la nozione di chiusure che, grosso modo, cattura una funzione insieme a legami di variabili. inoltre l'uso pervasivo delle chiusure, ci sono alcuni altri tratti distintivi nella programmazione funzionale, come l'uso di funzioni ricorsive e valori immutabili (entrambi giocano bene insieme). Questi tratti sono più un problema culturale che altro, e non c'è alcun impedimento tecnico per usarli praticamente in qualsiasi lingua, ecco perché mi concentro sulle chiusure nella mia risposta: non tutte le lingue permettono di creare facilmente chiusure.
Un tipico utilizzo delle chiusure è l'implementazione di meccanismi di privacy. Per esempio il codice Javascript - negli esempi ho scelto Javascript perché è un linguaggio funzionale con una cosiddetta "sintassi C-like" e la tua domanda suggerisce che hai familiarità con C:
create_counter = function()
{
var x = 0;
var counter = function()
{
++x;
return x;
};
return counter;
}
Quindi con
a = create_counter();
b = create_counter();
abbiamo due funzioni a
e b
conteggio delle raccolte disgiunte. Il punto dell'esempio è che le variabili x
vengono catturate dalla chiusura che definisce la chiusura counter
e ogni volta che una nuova counter
chiusura is instantiated by the function, it gets its fresh own idea of what
x 'è.
Un altro tipico utilizzo delle chiusure è la definizione di applicazioni parziali di funzioni. Supponiamo che abbiamo una funzione di reporting simile a syslog
che implementa una funzione
var log = function(priority, message) {
…
};
dove ci si aspetta che gli argomenti priority
e message
siano stringhe, il primo essendo uno di "debug"
, "info"
e così via. Possiamo definire una fabbrica di log come questa:
var logWithPriority = function(priority) {
return function(message) {
log(priority, message);
};
};
e usarlo per definire versioni specializzate della nostra funzione di registro:
var debug = logWithPriority("debug");
var info = logWithPriority("info");
…
Questo è molto utile, perché invece di scrivere% incline agli errori for
-loops come questo
for(i = 0; i < journal.length; ++i) {
log("info", journal[i]);
}
possiamo scrivere il pulitore, più breve e molto più semplice (non c'è i
, cioè molto migliore):
journal.forEach(logWithPriority("info"));
Un terzo importante campo di applicazione delle chiusure è l'implementazione della valutazione lazy - osserva che il supporto speciale delle lingue può fornire un'implementazione migliore.
Una funzione lazy, invece di eseguire un calcolo diretto, restituisce una chiusura che può essere chiamata (o "forzata" nel gergo della pigrizia) per eseguire la domanda. La motivazione per farlo è che separa la preparazione di un calcolo e l'esecuzione di un calcolo. Un esempio pratico di questo è la compilazione di espressioni regolari: se un programma compila un sacco di espressioni regolari all'avvio, avrà bisogno di molto tempo per iniziare. Se invece compiliamo pigramente le espressioni regolari e le forgiamo quando ne abbiamo bisogno, allora il nostro programma può iniziare rapidamente. Naturalmente, le espressioni regolari possono essere sostituite qui con qualsiasi struttura che richiede un tempo di inizializzazione considerevole.
Ecco come implementare la valutazione pigra con chiusure. Considera l'implementazione classica della funzione arrayMax che restituisce il massimo in un array:
function arrayMax(array) {
return array.reduce(function(a, b) {
return Math.min(a, b);
};
}
La variante pigra sarebbe:
function arrayMax(array) {
var memo = null;
function actuallyCompute() {
if(memo === null) {
memo = array.reduce(function(a, b) {
return Math.min(a, b);
});
}
return memo;
}
return actuallyCompute;
}
Il valore restituito è una chiusura che può essere utilizzata per calcolare il valore o recuperarlo un'altra volta se è già stato calcolato.
Con questi tre esempi, dovremmo essere certi che le chiusure e le loro applicazioni sono il fulcro della programmazione funzionale.
Imparare la programmazione funzionale significa imparare come programmare con chiusure. Di conseguenza, le lingue che consentono la facile manipolazione delle chiusure, e in particolare l'applicazione parziale delle funzioni, dovrebbero essere considerate quando si cerca una lingua per studiare la programmazione funzionale. Viceversa, le lingue in cui le chiusure non possono essere facilmente manipolate potrebbero essere scelte sbagliate.
Penso che gli strumenti che usi influenzino molto il tuo apprendimento. È quasi impossibile apprendere concetti di programmazione per i quali il linguaggio di programmazione che usi non fornisce i mezzi per farne uso. Certo, puoi sempre imparare alcune cose, ma non puoi impararlo correttamente.
Ma questo è comunque accademico, perché, come Martinho dice nel suo commento , anche se potrebbe imparare la programmazione funzionale, dovresti non provare a farlo, perché ci sono lingue in cui questo è molto più facile.
Non dovresti imparare la programmazione funzionale in C, ma in un linguaggio funzionale rigoroso (Haskell, Caml, Erlang, ecc.).
Se sei nuovo nel funzionamento, non lo otterrai mai con un linguaggio non funzionale. Più probabilmente ti allenerai a fare ciò che pensi sia una programmazione funzionale e imparerai le cose nel modo sbagliato. Ed è sempre più difficile "riapprendere" le cose nel modo giusto che non averle imparate nel modo giusto all'inizio.
Ad ogni modo, penso che fare funzioni in C sia un buon esercizio per qualcuno che già conosce funzionale. Perché quella persona imparerà cosa sta succedendo dietro le quinte - ciò che il computer sta davvero facendo.