Laut Wikipedia ist Ruby eine funktionale Sprache, aber ich bin nicht überzeugt. Warum oder warum nicht?
Laut Wikipedia ist Ruby eine funktionale Sprache, aber ich bin nicht überzeugt. Warum oder warum nicht?
Antworten:
Ich denke auf jeden Fall, dass Sie in Ruby funktionalen Stil verwenden können.
Einer der wichtigsten Aspekte, um in einem funktionalen Stil programmieren zu können, ist, ob die Sprache Funktionen höherer Ordnung unterstützt ... was Ruby tut.
Das heißt, es ist einfach, in Ruby auch in einem nicht funktionalen Stil zu programmieren. Ein weiterer wichtiger Aspekt des Funktionsstils besteht darin, keinen Zustand zu haben und echte mathematische Funktionen zu haben, die für einen bestimmten Satz von Eingaben immer den gleichen Wert zurückgeben. Dies kann in Ruby durchgeführt werden, wird jedoch nicht in der Sprache erzwungen, wie dies bei etwas strengerem wie Haskell der Fall ist.
Ja, es unterstützt den funktionalen Stil, aber Sie können auch in einem nicht funktionalen Stil programmieren.
Is ruby a functional language?
und in einer klaren Antwort ein einfaches Nein ist. Ruby ist eine objektorientierte Sprache mit einigen Funktionsmerkmalen.
Ob eine Sprache eine funktionale Sprache ist oder nicht, ist unwichtig. Funktionale Programmierung ist eine These, die am besten von Philip Wadler (Die Essenz der funktionalen Programmierung) und John Hughes (Warum funktionale Programmierung wichtig ist) erklärt wird.
Eine aussagekräftige Frage lautet: "Wie zugänglich ist Ruby für die Erreichung der These der funktionalen Programmierung?" Die Antwort lautet "sehr schlecht".
Ich habe erst kürzlich einen Vortrag darüber gehalten. Hier sind die Folien.
Ruby unterstützt zwar übergeordnete Funktionen (siehe Array # Map, Inject & Select), ist jedoch weiterhin eine zwingende, objektorientierte Sprache.
Eines der Hauptmerkmale einer funktionalen Sprache ist, dass sie einen veränderlichen Zustand vermeidet. Funktionale Sprachen haben nicht das Konzept einer Variablen wie in Ruby, C, Java oder einer anderen imperativen Sprache.
Ein weiteres wichtiges Merkmal einer funktionalen Sprache ist, dass sie sich darauf konzentriert, ein Programm eher als "was" als als "wie" zu definieren. Beim Programmieren in einer OO-Sprache schreiben wir Klassen und Methoden, um die Implementierung (das "Wie") vor dem "Was" (dem Klassen- / Methodennamen) zu verbergen, aber am Ende werden diese Methoden immer noch mit einer Folge von Anweisungen geschrieben. In einer funktionalen Sprache geben Sie selbst auf der untersten Ebene keine Ausführungssequenz an.
Ich behaupte, dass die Unterstützung oder die Fähigkeit, in einer Sprache in einem funktionalen Stil zu programmieren, keine funktionale Sprache darstellt.
Ich kann sogar Java-Code in einem funktionalen Stil schreiben, wenn ich meine Kollegen und mich selbst einige Monate später verletzen möchte .
Eine funktionale Sprache ist nicht nur über das, was Sie können tun, wie Funktionen höherer Ordnung, erstklassige Funktionen und Striegeln. Es geht auch darum, was Sie nicht tun können, wie Nebenwirkungen in reinen Funktionen.
Dies ist wichtig, da dies ein großer Teil des Grundes dafür ist, warum Funktionsprogramme oder Funktionscode im Allgemeinen leichter zu überlegen sind. Und wenn es einfacher ist, über Code nachzudenken, werden Fehler flacher und schweben zur konzeptionellen Oberfläche, wo sie behoben werden können, was wiederum weniger fehlerhaften Code ergibt.
Ruby ist im Kern objektorientiert. Obwohl es einen funktionalen Stil einigermaßen gut unterstützt, ist es selbst keine funktionale Sprache.
Das ist sowieso meine nicht-wissenschaftliche Meinung.
Bearbeiten: Rückblickend und unter Berücksichtigung der feinen Kommentare, die ich bisher zu dieser Antwort erhalten habe, denke ich, dass der objektorientierte versus funktionale Vergleich ein Vergleich zwischen Äpfeln und Orangen ist.
Das eigentliche Unterscheidungsmerkmal ist, ob man in der Ausführung unparteiisch ist oder nicht. Funktionale Sprachen haben den Ausdruck als primäres Sprachkonstrukt und die Reihenfolge der Ausführung ist oft undefiniert oder als faul definiert. Eine strikte Ausführung ist möglich, wird jedoch nur bei Bedarf verwendet. In einer unparteiischen Sprache ist die strikte Ausführung die Standardeinstellung, und obwohl eine verzögerte Ausführung möglich ist, ist dies häufig umständlich und kann in vielen Randfällen zu unvorhersehbaren Ergebnissen führen.
Nun, das ist mein nicht-wissenschaftliches Gutachten.
Ruby muss die folgenden Anforderungen erfüllen, um "WIRKLICH" funktionsfähig zu sein.
Unveränderliche Werte: Sobald eine „Variable“ festgelegt ist, kann sie nicht mehr geändert werden. In Ruby bedeutet dies, dass Sie Variablen effektiv wie Konstanten behandeln müssen. Das wird in der Sprache nicht vollständig unterstützt, Sie müssen jede Variable manuell einfrieren.
Keine Nebenwirkungen: Wenn ein bestimmter Wert übergeben wird, muss eine Funktion immer das gleiche Ergebnis zurückgeben. Dies geht einher mit unveränderlichen Werten; Eine Funktion kann niemals einen Wert annehmen und ändern, da dies einen Nebeneffekt verursachen würde, der tangential zur Rückgabe eines Ergebnisses ist.
Funktionen höherer Ordnung: Dies sind Funktionen, die Funktionen als Argumente zulassen oder Funktionen als Rückgabewert verwenden. Dies ist wohl eines der kritischsten Merkmale jeder funktionalen Sprache.
Currying: Durch Funktionen höherer Ordnung aktiviert, transformiert Currying eine Funktion, die mehrere Argumente akzeptiert, in eine Funktion, die ein Argument akzeptiert. Dies geht Hand in Hand mit einer Teilfunktionsanwendung, bei der eine Funktion mit mehreren Argumenten in eine Funktion umgewandelt wird, die weniger Argumente benötigt als ursprünglich.
Rekursion: Schleife durch Aufrufen einer Funktion aus sich heraus. Wenn Sie keinen Zugriff auf veränderbare Daten haben, wird die Rekursion zum Aufbau und zur Verkettung der Datenkonstruktion verwendet. Dies liegt daran, dass Schleifen kein Funktionskonzept sind, da Variablen übergeben werden müssen, um den Status der Schleife zu einem bestimmten Zeitpunkt zu speichern.
Lazy-Evaluation oder Delayed-Evaluation: Verzögerung der Verarbeitung von Werten bis zu dem Zeitpunkt, an dem sie tatsächlich benötigt werden. Wenn Sie beispielsweise einen Code haben, der eine Liste von Fibonacci-Zahlen mit aktivierter Lazy-Evaluierung generiert, wird dieser erst verarbeitet und berechnet, wenn einer der Werte im Ergebnis von einer anderen Funktion, z. B. Puts, benötigt wurde.
Vorschlag (nur ein Gedanke)
Ich wäre großartig, wenn ich eine Definition hätte, um eine mode
Direktive zum Deklarieren von Dateien mit funktionalem Paradigma zu haben, zum Beispiel
Modus 'funktional'
Ruby ist eine objektorientierte Sprache, die andere Paradigmen unterstützen kann (funktional, imperativ usw.). Da jedoch alles in Ruby ein Objekt ist, handelt es sich in erster Linie um eine OO-Sprache.
Beispiel:
"hallo" .reverse () = "olleh", jeder String ist eine String-Objektinstanz und so weiter und so fort.
Dies hängt von Ihrer Definition einer „funktionalen Sprache“ ab. Persönlich denke ich, dass der Begriff selbst ziemlich problematisch ist, wenn er als Absolut verwendet wird. Das sind mehr Aspekte, um eine „funktionale Sprache“ zu sein, als bloße Sprachmerkmale und die meisten hängen davon ab, von wo aus Sie suchen. Zum Beispiel ist die Kultur, die die Sprache umgibt, in dieser Hinsicht sehr wichtig. Fördert es einen funktionalen Stil? Was ist mit den verfügbaren Bibliotheken? Ermutigen sie Sie, sie funktional zu nutzen?
Die meisten Leute würden Scheme zum Beispiel eine funktionale Sprache nennen. Aber was ist mit Common Lisp? Abgesehen von dem Problem mit mehreren / einzelnen Namespaces und der garantierten Eliminierung von Tail-Calls (die einige CL-Implementierungen je nach Compilereinstellungen ebenfalls unterstützen), ist Scheme als Sprache für die funktionale Programmierung nicht viel besser geeignet als Common Lisp und dennoch würden die meisten Lisper CL nicht als funktionale Sprache bezeichnen. Warum? Weil die Kultur, die sie umgibt, stark von den zwingenden Merkmalen von CL abhängt (wie zum Beispiel das LOOP-Makro, das die meisten Schemers wahrscheinlich missbilligen würden).
Andererseits kann ein C-Programmierer CL durchaus als funktionale Sprache betrachten. Der meiste Code, der in einem Lisp-Dialekt geschrieben wurde, ist sicherlich viel funktionaler als Ihr üblicher C-Code-Block. Ebenso ist Scheme im Vergleich zu Haskell eine sehr wichtige Sprache. Daher glaube ich nicht, dass es jemals eine eindeutige Ja / Nein-Antwort geben kann. Ob Sie eine funktionale Sprache aufrufen oder nicht, hängt stark von Ihrem Standpunkt ab.
Ruby ist auch nicht wirklich eine Multi-Paradigmen-Sprache, denke ich. Multi-Paradigma wird in der Regel von Menschen verwendet, die ihre Lieblingssprache als etwas bezeichnen möchten, das in vielen verschiedenen Bereichen nützlich ist.
Ich würde beschreiben, dass Ruby eine objektorientierte Skriptsprache ist. Ja, Funktionen sind erstklassige Objekte, aber das macht sie nicht wirklich zu einer funktionalen Sprache. IMO, könnte ich hinzufügen.
Rekursion ist in der funktionalen Programmierung üblich. Fast jede Sprache unterstützt die Rekursion, aber rekursive Algorithmen sind oft ineffektiv, wenn keine Tail Call Optimization (TCO) vorhanden ist.
Funktionale Programmiersprachen können die Schwanzrekursion optimieren und diesen Code auf konstantem Raum ausführen. Einige Ruby-Implementierungen optimieren die Schwanzrekursion, andere nicht, aber im Allgemeinen sind keine Ruby-Implementierungen erforderlich, um TCO durchzuführen. Siehe Führt Ruby eine Tail Call-Optimierung durch?
Wenn Sie also einen Ruby-Funktionsstil schreiben und sich auf die Gesamtbetriebskosten einer bestimmten Implementierung verlassen, ist Ihr Code in einem anderen Ruby-Interpreter möglicherweise sehr ineffektiv. Ich denke, aus diesem Grund ist Ruby keine funktionale Sprache (Python auch nicht).
Genau genommen macht es keinen Sinn, eine Sprache als "funktional" zu beschreiben. Die meisten Sprachen können funktional programmiert werden. Sogar C ++ ist.
Der funktionale Stil ist mehr oder weniger eine Teilmenge der zwingenden Sprachfunktionen, die mit syntaktischem Zucker und einigen Compiler-Optimierungen wie Unveränderlichkeit und Abflachung der Schwanzrekursion unterstützt werden.
Letzteres ist wohl eine geringfügige implementierungsspezifische Technik und hat nichts mit der tatsächlichen Sprache zu tun. Der x64 C # 4.0-Compiler optimiert die Schwanzrekursion, während der x86-Compiler dies aus irgendeinem dummen Grund nicht tut.
Syntaktischer Zucker kann normalerweise auf die eine oder andere Weise umgangen werden, insbesondere wenn die Sprache einen programmierbaren Precompiler hat (dh Cs #define).
Es könnte etwas sinnvoller sein zu fragen: "Unterstützt Sprache __ imperative Programmierung?", Und die Antwort, zum Beispiel bei Lisp, lautet "Nein".
Bitte schauen Sie sich den Anfang des Buches an: "A-Great-Ruby-eBook" . Es wird das sehr spezifische Thema besprochen, das Sie fragen. In Ruby können Sie verschiedene Arten der Programmierung durchführen. Wenn Sie wie funktional programmieren möchten, können Sie dies tun. Wenn Sie wie unbedingt programmieren möchten, können Sie es tun. Es ist eine Definitionsfrage, wie funktional Ruby am Ende ist. Bitte beachten Sie die Antwort des Benutzers camflan.