Als Ergebnis der Kommentardiskussion hier frage ich mich, ob Sie funktionale Programmierung in C lernen können.
Als Ergebnis der Kommentardiskussion hier frage ich mich, ob Sie funktionale Programmierung in C lernen können.
Antworten:
Natürlich können Sie funktionale Programmierung in C durchführen. Theoretisch können Sie auch funktionale Programmierprinzipien in C lernen , aber die Sprache macht es nicht einfach.
Ich gehe davon aus, dass Sie zumindest ein wenig Hintergrundwissen in OOP haben. Wenn Sie dies tun, sollten Sie sich darüber im Klaren sein, dass OOP in C durchgeführt werden kann, einschließlich Polymorphismus, Getter / Setter, Sichtbarkeitsregeln usw. usw., aber es ist ziemlich schmerzhaft, dies zu tun, und Sie müssen sowohl OOP als auch C im Inneren kennen. herausziehen. Bei FP ist es ähnlich.
Was Sie tun sollten , ist zuerst eine funktionale Programmiersprache zu lernen (die meisten von ihnen haben überraschend einfache Syntaxregeln; es ist nicht die Syntax, die sie schwer zu erlernen macht) und dann Ihre neu erworbene Weisheit die Art und Weise beeinflussen zu lassen, wie Sie C schreiben.
Auf Anfrage können Sie einige Dinge von FP lernen und dann beispielsweise in C, C ++ oder Java anwenden:
C kann gehackt werden, um einige funktionale Konzepte anzubieten:
Diese StackOverflow-Frage sagt Ihnen mehr. Obwohl es möglich zu sein scheint, funktionale Programmierung (oder eine große Teilmenge davon) in C durchzuführen, sind Hacks und Compiler-Erweiterungen und was auch immer nicht der beste Weg, um ein Konzept kennenzulernen.
Um funktionales Programmieren tatsächlich zu lernen, ist eine der bekanntesten funktionalen Programmiersprachen wie Lisp und seine Dialekte ( Clojure , Scheme ), Erlang und Haskell die beste Wahl . Jedes dieser Tools ist perfekt, um innerhalb der Denkweise der funktionalen Programmierung zu arbeiten. F # ist auch ein guter Kandidat, wenn Sie einen .Net-Hintergrund haben, aber es ist eine Multi-Paradigmen-Sprache, nicht ausschließlich eine funktionale Programmiersprache.
Wie tdammers in den Kommentaren feststellt:
Tatsächlich sind LISP, Clojure und Schema auch Multi-Paradigmen. Haskell ist zwar rein und standardmäßig faul, ermöglicht jedoch auch eine zwingende Programmierung in einem monadischen Kontext und bietet umfassende Unterstützung für die gleichzeitige Verarbeitung. Alle diese Mechanismen verfügen über Mechanismen, die große Teile der in der OOP-Welt gesammelten Weisheit umsetzen - Kapselung, Vererbung, Einzelverantwortung, Zusammensetzung usw. Es geht nicht so sehr darum, ob eine Sprache andere Paradigmen zulässt. Es geht darum, welches Paradigma den Ausgangspunkt einer Sprache bildet.
Nach meinem besten Wissen sind Lisp und seine Dialekte und Erlang bessere Kandidaten als F #, weil sie die funktionale Programmierung gegenüber anderen Paradigmen fördern , was tdammers wunderbar als Ausgangspunkt einer Sprache angibt . F # umfasst funktionale Programmierung, ermutigt sie jedoch nicht gegenüber anderen unterstützten Paradigmen, der imperativen und der oo-Programmierung.
Sie können in C nicht alle Aspekte der funktionalen Programmierung lernen. Sicherlich können Sie die funktionale Programmierung mit jeder beliebigen Sprache beginnen. Diese Startbits sind: "Wie man die Dinge beim Programmieren rein hält." Und es kann auch C gemacht werden. Überprüfen Sie diesen Blog-Beitrag für Details-
http://www.johndcook.com/blog/2011/07/24/get-started-functional-programming/
Bei der funktionalen Programmierung geht es um Verschlüsse und deren Anwendungen. Vergessen Sie die Verwendung von C, um die funktionale Programmierung zu erlernen, es sei denn, jemand kann Ihnen eine Abstiegsschließungsbibliothek für C zeigen.
Das Hauptkonzept der funktionalen Programmierung ist der Begriff der Verschlüsse, der grob gesagt eine Funktion zusammen mit Variablenbindungen erfasst. Neben der allgegenwärtigen Verwendung von Verschlüssen gibt es einige andere charakteristische Merkmale in der funktionalen Programmierung, wie die Verwendung von rekursiven Funktionen und unveränderlichen Werten (beide spielen gut zusammen). Diese Merkmale sind mehr ein kulturelles Problem als alles andere, und es gibt kein technisches Hindernis, sie in praktisch jeder Sprache zu verwenden. Deshalb konzentriere ich mich in meiner Antwort auf Verschlüsse: Nicht jede Sprache erlaubt es, einfach Verschlüsse zu erstellen.
Eine typische Verwendung von Schließungen ist die Implementierung von Datenschutzmechanismen. Zum Beispiel der Javascript-Code - in den Beispielen habe ich Javascript ausgewählt, weil es eine funktionale Sprache mit einer sogenannten „C-ähnlichen Syntax“ ist und Ihre Frage darauf hindeutet, dass Sie mit C vertraut sind:
create_counter = function()
{
var x = 0;
var counter = function()
{
++x;
return x;
};
return counter;
}
Dann mit
a = create_counter();
b = create_counter();
Wir haben zwei Funktionen a
und b
zählen disjunkte Sammlungen. Der Punkt des Beispiels ist, dass die Variablen x
durch den Abschluss erfasst werden, der den Abschluss definiert, counter
und jedes Mal, wenn ein neuer counter
Abschluss is instantiated by the function, it gets its fresh own idea of what
x` ist.
Eine andere typische Verwendung von Verschlüssen ist die Definition von Teilanwendungen von Funktionen. Angenommen, wir haben eine Berichtsfunktion, die der syslog
Implementierung einer Funktion ähnelt
var log = function(priority, message) {
…
};
wo die Argumente priority
und message
voraussichtlich Zeichenfolgen sind, wobei das erste eines von "debug"
ist "info"
, und so weiter. Wir können eine Protokollfabrik wie folgt definieren:
var logWithPriority = function(priority) {
return function(message) {
log(priority, message);
};
};
und verwenden Sie es, um spezielle Versionen unserer Protokollfunktion zu definieren:
var debug = logWithPriority("debug");
var info = logWithPriority("info");
…
Dies ist sehr nützlich, da anstatt fehleranfällige for
Schleifen wie diese zu schreiben
for(i = 0; i < journal.length; ++i) {
log("info", journal[i]);
}
wir können das sauberere, kürzere und viel einfachere schreiben (es gibt kein i
, das ist viel besser):
journal.forEach(logWithPriority("info"));
Ein drittes wichtiges Anwendungsfeld von Schließungen ist die Implementierung einer verzögerten Evaluierung. Beachten Sie, dass eine spezielle Sprachunterstützung für eine bessere Implementierung sorgen kann.
Eine Lazy-Funktion gibt anstelle einer direkten Berechnung einen Abschluss zurück, der aufgerufen (oder im Jargon der Faulheit „gezwungen“) werden kann, um die Frage auszuführen. Die Motivation dafür ist, dass es die Vorbereitung einer Berechnung und die Durchführung einer Berechnung trennt. Ein praktisches Beispiel hierfür ist die Kompilierung regulärer Ausdrücke: Wenn ein Programm beim Start viele reguläre Ausdrücke kompiliert, benötigt es viel Zeit zum Starten. Wenn wir stattdessen die regulären Ausdrücke träge kompilieren und sie nach Bedarf erzwingen, kann unser Programm schnell gestartet werden. Natürlich können reguläre Ausdrücke hier durch jede Struktur ersetzt werden, die eine beträchtliche Initialisierungszeit erfordert.
Hier erfahren Sie, wie Sie eine verzögerte Auswertung mit Abschlüssen implementieren. Betrachten wir die klassische Umsetzung der arrayMax Funktion , um die Rückkehr max in einem Array:
function arrayMax(array) {
return array.reduce(function(a, b) {
return Math.min(a, b);
};
}
Die faule Variante wäre:
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;
}
Der zurückgegebene Wert ist ein Abschluss, mit dem der Wert berechnet oder ein anderes Mal abgerufen werden kann, wenn er bereits berechnet wurde.
Mit diesen drei Beispielen sollten wir sicher sein, dass Verschlüsse und ihre Anwendungen den Kern der funktionalen Programmierung bilden.
Das Erlernen der funktionalen Programmierung bedeutet das Erlernen des Programmierens mit Verschlüssen. Infolgedessen sollten Sprachen, die die einfache Manipulation von Verschlüssen und insbesondere die teilweise Anwendung von Funktionen ermöglichen, bei der Suche nach einer Sprache zum Studium der funktionalen Programmierung berücksichtigt werden. Umgekehrt wären Sprachen, in denen Schließungen nicht einfach manipuliert werden können, eine schlechte Wahl.
Ich denke, dass die Werkzeuge, die Sie verwenden, Ihr Lernen stark beeinflussen. Es ist fast unmöglich, Programmierkonzepte zu lernen, für die die von Ihnen verwendete Programmiersprache nicht die Mittel bietet, die Sie verwenden können. Sicher, Sie können immer ein paar Dinge lernen, aber Sie können es nicht richtig lernen.
Aber das ist trotzdem akademisch, denn wie Martinho in seinem Kommentar sagt , sollten Sie nicht versuchen, dies zu tun , auch wenn Sie funktionale Programmierung lernen könnten , da es Sprachen gibt, in denen dies viel einfacher ist.
Sie sollten funktionale Programmierung nicht in C lernen, sondern in einer strengen funktionalen Sprache (Haskell, Caml, Erlang usw.)
Wenn Sie neu in der Funktion sind, werden Sie es nie wirklich mit einer nicht funktionalen Sprache bekommen. Wahrscheinlicher ist, dass Sie sich darin üben, das zu tun, was Sie für funktionale Programmierung halten, und die Dinge falsch lernen. Und es ist immer schwieriger, Dinge richtig neu zu lernen, als sie zuerst richtig zu lernen.
Wie auch immer, ich denke, funktional in C zu sein ist eine gute Übung für jemanden, der funktional bereits kennt. Weil diese Person lernen wird, was sich hinter der Haube abspielt - was der Computer wirklich tut.