Unterscheidet sich die funktionale Programmierung oder ist sie wirklich schwieriger ?
Sagen wir, jemand, der noch nie Programmieren gelernt hat und in funktionalem Programmieren unterrichtet wird. gegen jemanden, der das Programmieren noch nie erlernt hat und der das Imperative Programmieren gelernt hat. was wird er härter finden? oder das selbe?
Meine frage: sag mal das problem ist jetzt einen eingang zu camel-case,
so qwe_asd_zxc_rty_fgh_vbn
wird dasqweAsdZxcRtyFghVbn
Der prozedurale Weg ist:
- Teilen Sie es entlang der
_
- Durchlaufen Sie das Array und überspringen Sie das erste Element
- Für jeden Eintrag wird der erste Buchstabe in Großbuchstaben geschrieben
- Füge die Ergebnisse zusammen
Die Funktionsweise ist:
- Wenn keine
_
Rückgabe möglich istinput
- schneide die
input
entlang der ersten_
(so dass wir bekommenqwe
undasd_zxc_rty_gfh_cvb
) - Schreiben Sie den ersten Buchstaben von
head
groß und schreiben Sie ihn mitf(tail)
Ok, wenn Sie einen funktionalen Hintergrund und umfangreiche Erfahrung in der prozeduralen Programmierung haben, möchte ich Sie fragen: Werden Sie länger brauchen, um den prozeduralen Weg zu finden, oder werden Sie länger brauchen, um den funktionalen Weg zu finden?
Wenn Sie einen prozeduralen Hintergrund haben, aber langjährige Erfahrung mit funktionaler Programmierung haben, möchte ich dieselbe Frage stellen: Werden Sie länger brauchen, um den prozeduralen Weg zu finden, oder werden Sie länger brauchen, um das Funktionale herauszufinden? Weg?
map
für Schritt 3 anstelle einer mutierenden Schleife verwenden. Der zweite Ansatz würde ich nur in Betracht ziehen, wenn es in der Standardbibliothek keine Teilungsfunktion gibt (in diesem Fall sollte er mit einer Imperativlösung verglichen werden, die ebenfalls keine verwendetsplit
).x=x+1
kann ein unerwartetes Gehirn in die Luft jagen. Funktionale Programmierung ist selbstverständlich, sie ist nichts anderes als reine und zweckmäßige rein mathematische Funktionen.Antworten:
Einfach anders. Die funktionale Programmierung ist viel enger mit der Mathematik verwandt, mit der die meisten Menschen vertraut sind. Die ganze Sache mit den "unveränderlichen Variablen" ist nur für imperative Programmierer ein Schock, bei denen die "veränderliche" Denkweise tief verwurzelt ist.
Für Neulinge ist es oft ziemlich intuitiv, dass man den Wert von etwas nicht einfach ändern kann.
Während meines CS-Studiums wurde uns als allererster Kurs eine funktionale Sprache beigebracht. Und jeder, der zuvor C ++ oder Java gelernt hatte, hatte damit zu kämpfen. Diejenigen, die neu in der Programmierung waren, nahmen es ziemlich leicht auf.
quelle
Es ist einfach anders
Wenn Sie programmieren, übersetzen Sie im Wesentlichen die Art und Weise, wie Sie argumentieren, in Code. Die Distanz zwischen Ihren Gedanken und der endgültigen Lösung kann als "kognitive Lücke" bezeichnet werden. Je größer die Lücke, desto schwieriger wird es für Sie, sie zu überbrücken.
Wenn Sie einen prozeduralen Hintergrund haben, haben Sie sich darin geschult, prozedural zu denken, sodass die Lücke geringer ist als bei funktionalem Code und umgekehrt.
Die einzige Möglichkeit, ein Programmierparadigma von sich aus einfacher zu gestalten als alles andere, besteht darin, es auf etwas abzubilden, das Sie bereits kannten, wie z.
Funktionell und prozedural ist sowieso ein ziemlich fließendes Konzept und sie neigen dazu, sich zu überschneiden
quelle
Ja, funktionale Programmierung ist für viele Menschen schwer nachvollziehbar (ich würde eher sagen, besonders für diejenigen, die zuvor bereits mit prozeduraler Programmierung konfrontiert waren).
Ich würde auch sagen, dass Ihr Beispiel für funktionale Programmierung kein wirklich gutes Beispiel für funktionale Programmierung ist. Es wird eine Rekursion verwendet und nur ein Ergebnis erstellt, anstatt den Status zu ändern, aber nicht viel mehr.
Um ein besseres Beispiel für funktionale Programmierung zu erhalten, betrachten Sie ein allgemeineres Problem: Anstatt nach einem Unterstrich zu suchen und den nächsten Buchstaben in Großbuchstaben umzuwandeln, betrachten Sie dies als einen Sonderfall, bei dem nach einem Muster gesucht und ein beliebiger Code ausgeführt wird, wenn es ist gefunden.
Viele Sprachen unterstützen dies, aber dazu müssen wir das Muster als einen regulären Ausdruck definieren. Reguläre Ausdrücke sind jedoch nichts anderes als eine spezielle Programmiersprache, und eine RE-Implementierung ist ein Compiler und / oder Interpreter für diese Sprache. Das Ergebnis des Kompilierens der RE ist im Grunde eine Funktion, die (in einer speziellen virtuellen RE-Maschine) ausgeführt wird, um den Ausdruck mit einer Eingabe abzugleichen.
In etwas wie Perl verwenden Sie eine spezielle Sprache, um das Muster anzugeben, und einen speziellen Compiler, um diesen String in eine Art funktionsähnliches Element zu konvertieren, und einen speziellen Interpreter, um dieses funktionsähnliche Element zur Ausführung zu bringen. In einer funktionalen Sprache verwenden Sie normalerweise die Sprache selbst, um das Muster anzugeben, und verwenden den eigenen Compiler der Sprache, um eine echte Funktion zu erstellen . Wir können diese Funktion im laufenden Betrieb generieren (etwa so, als könnten wir eine RE kompilieren, wenn wir wollen), aber wenn wir dies tun, kann das Ergebnis wie jede andere Funktion in der Sprache ausgeführt werden, anstatt dafür spezielle RE-Funktionen zu benötigen.
Das Ergebnis ist , dass wir können das Problem oben relativ leicht verallgemeinern. Anstatt das '_' und "Großbuchstaben" direkt in die Transformation zu codieren, können wir jedoch Folgendes haben:
Aber im Gegensatz zu etwas, bei dem wir das Muster als RE spezifizieren, können wir das Muster direkt als echte Funktion spezifizieren und es trotzdem verwenden, so etwas wie:
Und dann übergeben wir diese Funktion dem s & r. Im Moment ist es eine ziemlich triviale Funktion und wir haben sie vollständig statisch codiert. Eine funktionale Sprache wird zum größten Teil interessant, wenn wir sie so verwenden, als könnten wir REs erstellen und eine völlig neue Funktion erstellen, die auf Benutzereingaben basiert. Im Gegensatz zu einer RE benötigt diese Funktion jedoch keinen speziellen RE-Interpreter Nur eine normale Funktion wie jede andere.
quelle
Hier ist der vollständige Code in Racket :
Als funktionaler Programmierer mit prozeduraler Erfahrung glaube ich nicht, dass ich länger brauchen würde, um eine prozedurale Lösung "herauszufinden", aber ich würde sicherlich länger brauchen, um sie einzutippen.
Übrigens ist das erwartete Beispielergebnis im ursprünglichen Beitrag falsch: Am Ende fehlt ein "h".
quelle
Meine Haustier-Theorie ist, dass Programmiermodelle leichter zu verstehen sind, je näher sie an der tatsächlichen Arbeitsweise von Computern liegen. Zeiger sind schwer zu verstehen, bis Sie erkennen, dass es sich im Wesentlichen um Computeradressen handelt. Die Rekursion ist schwer zu verstehen, bis Sie bewusst ein kleines Beispiel durchgegangen sind, die Stapelrahmen gesehen und erkannt haben, wo die verschiedenen Werte derselben Variablen gespeichert sind. Das bedeutet nicht, dass Assembler-Programmierung einfacher ist als High-Level-Programmierung, aber zu sehen, wie es gemacht wird, wirkt sich positiv auf das mentale Modell aus, das den Schlüssel zur Kompetenz darstellt - ob in der Programmierung oder in der allgemeinen Benutzerfreundlichkeit.
Das Vorgehensmodell ist der üblichen Maschinenarchitektur etwas näher gekommen: Zuweisungen sind Speicher- (oder Registerschreibvorgänge). Prozeduraufrufe sind eigentlich nur ausgefallene Sprünge, ein
if
bedingter Sprung usw. In Lisp zum Beispiel gibt es kein einfaches Low-Level-Äquivalent zu einer lexikalischen Bindung oder einem Lambda-Ausdruck. Um dies zu verstehen, müssen Sie sich eine völlig separate abstrakte funktionale Maschine zwischen der Sprachebene und der physischen Maschine vorstellen, da und anscheinend die meisten Menschen nie so weit kommen.(Ich bin vertraut mit der Idee , dass die von Neumann - Architektur letztlich willkürlich ist, und wir sollen nicht Vorurteil Anfänger Köpfe mit solchen irrelevanten Details der Maschinenarchitektur und stattdessen direkt führen sie in die Semantik von Programmiersprachen. In der Tat, ich habe Ich habe selbst ein paar solcher Kurse unterrichtet, aber immer mehr empfinde ich dies als ein nobles, aber fehlgeleitetes Ziel: Die Leute lernen das Programmieren, indem sie das Verständnis von unten aufbauen, und der Weg zum funktionalen Programmieren ist einfach etwas länger.)
quelle
011011001001101...
wären die tatsächlichen Bytecodes die am einfachsten zu erlernende Sprache!