Es ist schwierig, genau zu definieren, was eine "funktionale Sprache" ist - von den von Ihnen aufgelisteten Sprachen ist nur Haskell rein funktional (alle anderen verwenden einen hybriden Ansatz). Es gibt jedoch einige Sprachfunktionen, die für die funktionale Programmierung sehr hilfreich sind, und Ruby und Python haben nicht genug davon, um für FP sehr gute Umgebungen zu sein. Hier ist meine persönliche Checkliste in der Reihenfolge ihrer Wichtigkeit:
- Erstklassige Funktionen und Abschlüsse (Ruby, Python und alle anderen, die Sie aufgelistet haben).
- Garantierte Tail-Call-Optimierung (Erlang, Haskell, Scala und Scheme haben dies, aber (noch) nicht Python, Ruby oder Clojure).
- Unterstützung für Unveränderlichkeit in den Sprach- und Standardbibliotheken (dies ist eine große, die alle "funktionalen Sprachen" haben, die Sie aufgelistet haben (außer Schema), aber Ruby und Python nicht).
- Sprachunterstützung für referenziell transparente (oder reine) Funktionen (soweit ich weiß, hat dies derzeit nur Haskell).
Der Bedarf an (1) sollte offensichtlich sein - Funktionen höherer Ordnung sind ohne erstklassige Funktionen äußerst schwierig. Wenn Leute darüber reden, dass Ruby und Python gute Sprachen für FP sind, reden sie normalerweise darüber. Diese spezielle Funktion ist jedoch notwendig, aber nicht ausreichend, um eine Sprache für FP zu verbessern.
(2) ist seit der Erfindung von Scheme eine traditionelle Notwendigkeit für FP. Ohne TCO ist es unmöglich, mit tiefer Rekursion zu programmieren, was einer der Eckpfeiler von FP ist, da Stapelüberläufe auftreten. Die einzige "funktionale" Sprache (laut populärer Definition), die dies nicht bietet, ist Clojure (aufgrund der Einschränkungen der JVM), aber Clojure verfügt über eine Vielzahl von Hacks, um die Gesamtbetriebskosten zu simulieren. (Zu Ihrer Information, Ruby TCO ist implementierungsspezifisch , aber Python unterstützt es nicht speziell .) Der Grund, warum TCO garantiert werden muss, ist, dass tief rekursive Funktionen bei einigen Implementierungen nicht funktionieren, so dass Sie es nicht wirklich können benutze sie überhaupt.
(3) ist eine weitere große Sache, die moderne funktionale Sprachen (insbesondere Haskell, Erlang, Clojure und Scala) nicht haben, wie Ruby und Python. Ohne zu sehr ins Detail zu gehen, beseitigt die garantierte Unveränderlichkeit ganze Klassen von Fehlern, insbesondere in gleichzeitigen Situationen, und ermöglicht saubere Dinge wie dauerhafte Datenstrukturen . Es ist sehr schwierig, diese Vorteile ohne Sprachunterstützung zu nutzen.
(4) ist für mich das Interessanteste an rein funktionalen Sprachen (im Gegensatz zu Hybridsprachen). Betrachten Sie die folgende extrem einfache Ruby-Funktion:
def add(a, b)
a + b
end
Dies sieht nach einer reinen Funktion aus, kann jedoch aufgrund der Überladung des Operators zu einer Veränderung der Parameter oder zu Nebenwirkungen wie dem Drucken auf der Konsole führen. Es ist unwahrscheinlich, dass jemand den +
Bediener überlastet , um eine Nebenwirkung zu haben, aber die Sprache gibt keine Garantie. (Das Gleiche gilt für Python, auch wenn dies in diesem Beispiel möglicherweise nicht der Fall ist.)
In einer rein funktionalen Sprache hingegen gibt es Garantien auf Sprachebene, dass Funktionen referenziell transparent sind. Dies hat zahlreiche Vorteile: reine Funktionen können leicht gespeichert werden; Sie können einfach getestet werden, ohne auf irgendeinen globalen Zustand angewiesen zu sein. und Werte innerhalb der Funktion können träge oder parallel ausgewertet werden, ohne sich um Parallelitätsprobleme kümmern zu müssen. Haskell nutzt dies voll aus, aber ich weiß nicht genug über andere funktionale Sprachen, um zu wissen, ob sie es tun.
Trotzdem ist es möglich, FP-Techniken in fast jeder Sprache (sogar Java) einzusetzen. Zum Beispiel ist Googles MapReduce von funktionalen Ideen inspiriert, aber soweit ich weiß, verwenden sie keine "funktionalen" Sprachen für ihre großen Projekte (ich denke, sie verwenden hauptsächlich C ++, Java und Python).