Ist Ruby eine funktionale Sprache?


87

Laut Wikipedia ist Ruby eine funktionale Sprache, aber ich bin nicht überzeugt. Warum oder warum nicht?


4
Wahrscheinlich, weil Ihre Frage sehr kurz ist, obwohl ich persönlich überhaupt kein Problem damit habe!
ljs

Es gibt bereits gute Antworten, um sie zu ergänzen, ein paar Inhalte, die sich mit FP und Ruby befassen : code.google.com/p/tokland/wiki/RubyFunctionalProgramming slidehare.net/tokland/functional-programming-with-ruby-9975242
tokland

1
Wenn sich jemand für dieses Thema interessiert, schauen Sie sich dies bitte an und Sie werden erfahren, wie Ruby auf funktionale Weise verwendet werden kann, wo die Wurzeln der funktionalen Programmierung liegen, warum Ruby keine funktionale Sprache ist, auch wenn es in der Lage ist, funktional zu programmieren: youtube .com / watch? v = 5ZjwEPupybw
maddin2code

Antworten:


29

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.


4
Würden Sie anhand dieser Kriterien sagen, dass Smalltalk funktionsfähig ist, weil es Blöcke enthält?
OscarRyz

Gute Antwort, aber ein Trottel - Funktionen höherer Ordnung sind für einen funktionalen Stil nicht unbedingt erforderlich. Beispiel: Sie können einen Funktionsstil in Java erreichen (der keine Funktionen erster Klasse / höherer Ordnung hat), indem Sie Funktionsobjekte definieren und zusammensetzen, um den gleichen Effekt wie eine Funktion höherer Ordnung zu erzielen.
Mikera

2
Ich möchte nur sagen, dass @peter gefragt hat Is ruby a functional language?und in einer klaren Antwort ein einfaches Nein ist. Ruby ist eine objektorientierte Sprache mit einigen Funktionsmerkmalen.
Elias Perez

58

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.


3
In den Folien, die Sie gegeben haben, wurde nicht erwähnt, warum Ruby "für die Erreichung der FP-These sehr schlecht geeignet ist". Warum ist C # zugänglicher als Java (OK, einfachere anonyme Funktionen?)? Liegt es daran, dass Sie in Ruby globale Variablen haben können?
kizzx2

7
Nein, die Folien gehen nicht auf dieses Detail ein, da dies ein ziemlich umfangreiches Thema ist. Ruby erzwingt beispielsweise das Risiko einer übermäßigen Vereinfachung und erzwingt ein Bewertungsmodell (Call-by-Value), das die Nichtkompositionalität von Programmen sicherstellt. Die Auswirkungen können leicht unterschätzt werden. Ruby ist auch mit der Idee verheiratet, dass ein Programm eine Folge von Effekten ist. Das heißt, Ruby tut alles, um es schwierig / unlösbar zu machen, ein anderes Rechenmodell zu verwenden. Ich hoffe dieser kurze Kommentar hilft.
Tony Morris

2
+1 für den Hinweis auf die Mehrdeutigkeit bei der Klassifizierung von Sprachen als funktional. Zur Hölle, ich habe funktionales C geschrieben!
Eli

1
Warum ist C # zugänglicher als Ruby?
dan_l

1
Effektiv eine Nur-Link-Antwort, da sie den kritischen Teil der Erklärung (tatsächlich die gesamte Erklärung) an einen externen Link auslagert. Nachdem der Link gestorben ist, ist die Antwort unbrauchbar geworden.
ivan_pozdeev

34

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.


3
Ich stimme den meisten Ihrer Aussagen zu, bin jedoch nicht einverstanden mit "Funktionale Sprachen haben nicht das Konzept von Variablen wie in Java usw.". In haskell können Sie Variablen in reinen Funktionen verwenden, Sie können einer Variablen sogar eine Funktion zuweisen. Der größte Unterschied besteht darin, dass eine einmal zugewiesene Variable nicht mehr geändert werden kann.
HHC

6
HHC ist per Definition eine Variable, die sich ändern kann . Sie sprechen von Werten.
Scala Newb

In der Tat sind Haskells "nicht modifizierbare Variablen" nur konstante Funktionen ohne Parameter (Definitionen).
raindev

16

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.


Ich denke, Sie können Ruby viel besser als Java bezeichnen ... nein, Ruby ist nicht streng funktional, aber es ist ziemlich einfach, einen funktionalen Stil darin zu verwenden ... und ein Kollege mit nicht funktionalem Stil kann dies leicht wieder in nicht funktionsfähig ändern
Mike Stone

1
Ja, Mike, wenn Sie in einem funktionalen Stil codieren möchten, ist Ruby eine enorme Verbesserung gegenüber Java. Ich habe nur Java verwendet, um den Punkt nach Hause zu übertreiben und zu hämmern.
Chris Vest

Da D also reine Funktionen hat, würden Sie D eine funktionale Sprache nennen? digitalmars.com/d/2.0/function.html#pure-functions
Peter Burns

3
Viele Menschen betrachten Lisp- und Scheme-Funktionssprachen, hauptsächlich aufgrund der allgegenwärtigen Verwendung anonymer Funktionen. Und doch fehlen ihnen garantierte reine Funktionen. Die Beschränkung des Begriffs auf Sprachen, die reine Funktionen unterstützen, erscheint viel zu restriktiv.
Skymt

13

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 modeDirektive zum Deklarieren von Dateien mit funktionalem Paradigma zu haben, zum Beispiel

Modus 'funktional'


2
Bitte schön. Ich möchte Sie einladen, über funktionale Sprachen zu lesen. Lisp ist der Großelternteil aller funktionalen Sprachen, ML (CAML) und Erlang / Elixir. Es verändert wirklich Ihre Sicht der Dinge. Ich bin kaum ein Experte, aber ein ständiger Student der Informatik liest und lernt gerne neue Dinge.
Elias Perez

Gut organisierte Antwort. Hätte gerne eine zusätzliche Untersuchung darüber, wie gut Ruby diese Dinge unterstützt. Ich glaube, dass Funktionen höherer Ordnung, Currying und Rekursion in Ruby unterstützt / möglich sind. Bitte korrigieren Sie mich, wenn ich falsch liege.
Michael Dorst

9

Ruby ist eine Multi-Paradigmen-Sprache, die einen funktionalen Programmierstil unterstützt.


8
Beweise
vorlegen

4

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.

Lesen Sie hier oder hier


Ich habe nie wirklich verstanden, wie "alles ein Objekt ist" Ruby mehr OO macht. Ich stimme zu, dass Ruby in erster Linie OO ist, aber "alles ist ein Objekt" bedeutet wirklich nur, dass es keine "primitiven" Typen gibt, was sehr wenig Einfluss auf die Fähigkeit des Entwicklers hat, Programme im OO-Stil zu schreiben, da es primitive gibt Typen bedeutet im Allgemeinen nur, dass es vier oder fünf Typen gibt, die keine Methoden haben.
Michael Dorst

4

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.


Inwiefern ist Haskell keine rein funktionale Sprache? Oder wie wäre es mit Miranda (einer weniger bekannten funktionalen Programmiersprache)? Kurse.cs.washington.edu/courses/cse505/99au/functional/… "Haskell ist eine reine Standardfunktionssprache"
Barlop

2

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.


4
Der Sprachtyp wird durch die unterstützten Programmierstile definiert. Dies wird wiederum durch die Funktionen bestimmt, die es hat. Erstklassige und anonyme Funktionen = minimale funktionale Programmierung. Ruby unterstützt die OO-Programmierung, benötigt sie jedoch nicht: Sie müssen niemals eine Klasse definieren. Daher Multi-Paradigma.
Skymt

2

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).


TCO ist interessant, weil es das Verhalten des Programms wesentlich verändert. In bestimmten Fällen ist dies für das Programm nicht sichtbar, in anderen Fällen sind es beispielsweise Ausnahme-Backtraces. Daher ist es nicht immer eine angemessene Optimierung.
Ioquatix

2

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".


1

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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.