Ist Javascript eine funktionale Programmiersprache?

34
  • Ist Javascript eine funktionale Sprache? Ich weiß, es hat Objekte und Sie können OOP damit auch machen, aber ist es auch eine funktionale Sprache, kann es auf diese Weise verwendet werden?
  • Sie wissen, wie OOP die nächste Evolution in der Programmierung wurde / scheint. Bedeutet dies, dass 'Funktionale Programmierung' die nächste Evolution ist (Hinweis: Dies ist KEINE Aufforderung zur Stellungnahme, ABER eine Aufforderung zur faktenbasierten Beantwortung, und dieser Hinweis ist mehr für die Moderatoren als für die Mitwirkenden;)).
  • Ich lerne am besten anhand von Beispielen, vielleicht könnte jemand zeigen, wie man dieselbe Aufgabe auf eine OOP-Art und dann auf eine funktionale Programmierweise ausführt, um zu verstehen und zu vergleichen, was funktionale Programmierung tut / ist.

Um ehrlich zu sein, verstehe ich 'Functional Programming' nicht wirklich vollständig: P Ein Vergleich von Javascript mit funktionaler Programmierung kann also völlig falsch sein.

Funktionale Programmierung in einfachen Worten ausgedrückt: Ist es einfach der Vorteil von Abstration durch Verwendung anonymer Funktionen?

Oder ist das zu einfach? Auf einfache Weise ist OOP der Vorteil der Abstraktion durch Objekte, aber ich glaube, dass dies etwas zu einfach ist, um OOP zu beschreiben.

Ist dies ein gutes Beispiel für funktionale Programmierung? ...

Javascript OOP Beispiel:

// sum some numbers
function Number( v )
{ 
  this.val = v;
}

Number.prototype.add( /*Number*/ n2 )
{
    this.val += n2.val;
}

Funktionsprogrammierbeispiel:

function forEach(array, action) 
{
   for (var i = 0; i < array.length; i++)
       action(array[i]);
}  

function add(array)
{
    var i=0;
    forEach(array, function(n)
    {
        i += n;
    });
    return i;
}

var res = add([1,9]);
Marek
quelle
Dies hängt von der Definition der "funktionalen Programmiersprache" ab. Im weiteren Sinne kann es als die Fähigkeit verstanden werden, funktionale Werte mit geschlossenen Werten aufzubauen, dh ein "Lambda" -Konstrukt (im Sinne der Lambda-Rechnung) zu haben, und dann passt Javascript zur Rechnung.
Basile Starynkevitch
2
Or is that way too simple?Ja, das ist es. Anonyme Funktionen werden manchmal mit funktionalen Sprachen und Multi-Paradigmen-Sprachen assoziiert, die die funktionale Programmierung bevorzugen, aber sie sind kein eindeutiges Merkmal von funktionalen Sprachen. Aber wenn man sie als eine Implementierung von λ-Kalkül betrachtet, dann sind sie ein zentraler Bestandteil der funktionalen Programmierung. Der wichtigste Punkt ist, dass es nicht so einfach ist :)
yannis
Das Design von Javascript verhindert, dass Implementierungen eine Tail-Call-Optimierung durchführen können. In meinen Büchern verhindert das allein, dass es als funktional bezeichnet wird.
Dan_waterworth
I know it has objects & you can do OOP with it alsoNein, kannst du nicht. Es ist eine prototypbasierte Programmierung, die die Unterscheidung zwischen Klasse und Objekt beseitigt. Persönlich betrachte ich die prototypbasierte Programmierung auf dieser Basisebene als fehlerhaft.
RokL
Javascript ist keine funktionale Sprache, sicher hat es funktionale Merkmale, aber das gute alte imperative C auch. Tatsächlich hat jede Sprache die grundlegenden funktionalen Merkmale. Eine reine funktionale Sprache wie Haskell, ML usw. ist eine deklarative, keine imperative Sprache.
ALXGTV

Antworten:

72

Ist Javascript eine funktionale Sprache? Ich weiß, es hat Objekte und Sie können OOP damit auch machen, aber ist es auch eine funktionale Sprache, kann es auf diese Weise verwendet werden?

Manchmal sagen die Leute funktionale Programmierung, wenn sie imperative Programmierung oder prozedurale Programmierung meinen . Funktionale Programmierung ist genau genommen :

In der Informatik ist die funktionale Programmierung ein Programmierparadigma, das die Berechnung als Bewertung mathematischer Funktionen behandelt und Zustands- und veränderliche Daten vermeidet . Im Gegensatz zum imperativen Programmierstil, bei dem Zustandsänderungen im Vordergrund stehen, wird die Anwendung von Funktionen betont. Funktionale Programmierung hat ihre Wurzeln in der Lambda-Rechnung, einem formalen System, das in den 1930er Jahren entwickelt wurde, um Funktionsdefinition, Funktionsanwendung und Rekursion zu untersuchen. Viele funktionale Programmiersprachen können als Ausarbeitungen der Lambda-Rechnung angesehen werden.

Obwohl Javascript nicht allgemein bekannt ist oder als funktionale Sprache verwendet wird, hat es einige funktionale Elemente :

JavaScript hat viel mit Schema gemeinsam. Es ist eine dynamische Sprache. Es verfügt über einen flexiblen Datentyp (Arrays), mit dem S-Ausdrücke einfach simuliert werden können. Und vor allem sind Funktionen Lambdas.

Schema ist ein Lisp- Dialekt und wahrscheinlich eine der Sprachen, an die die meisten Programmierer denken, wenn sie über funktionale Programmierung sprechen. Bei der Objektorientierung ist Javascript eine objektorientierte Sprache. Die Objektorientierung basiert jedoch auf Prototypen :

Die prototypbasierte Programmierung ist ein Stil der objektorientierten Programmierung, bei dem Klassen nicht vorhanden sind. Die Wiederverwendung des Verhaltens (in klassenbasierten Sprachen als Vererbung bezeichnet) erfolgt durch Klonen vorhandener Objekte, die als Prototypen dienen. Dieses Modell kann auch als klassenlose, prototypenorientierte oder instanzbasierte Programmierung bezeichnet werden. Die Delegierung ist die Sprachfunktion, die die prototypbasierte Programmierung unterstützt.

Obwohl Javascript objektorientiert ist, folgt es nicht dem gängigeren klassenbasierten Modell , ebenso wenig wie Sprachen wie C ++, C #, Java und PHP (und einige andere). Und natürlich ist es auch eine imperative Sprache, die zu der Verwechslung mit der oben beschriebenen funktionalen Programmierung führt.

Sie wissen, wie OOP die nächste Evolution in der Programmierung wurde / scheint. Bedeutet das, dass 'Functional Programming' die nächste Evolution ist?

Objektorientierung und funktionale Programmierung sind nur zwei von vielen verschiedenen Programmierparadigmen , sie sind unterschiedliche Programmierstile mit unterschiedlichen Konzepten und Abstraktionen. Das Schlüsselwort ist "anders". Es gibt kein einziges Paradigma, das besser als andere oder weiterentwickelt als andere ist. Jedes einzelne passt besser zu bestimmten Szenarien als die anderen. Einige sind möglicherweise älter als andere, aber evolutionär gesehen sind sie dadurch besser, da sie länger überlebt haben. Aber das ist keine sehr kluge Sichtweise.

Javascript ist, wie ich oben und einige andere Sprachen beschrieben habe, ein Multiparadigma. Sie können Code in einem imperativen, prototypbasierten, objektorientierten und funktionalen Stil schreiben. Es liegt an Ihnen zu entscheiden, welches am besten zu dem passt, was Sie bauen. Es gibt auch mehrere einzelne Paradigmasprachen, das kanonische Beispiel ist Java, das nur eine klassenbasierte objektorientierte Programmierung ermöglicht 1 .

Sie sollten wirklich jedem Drang widerstehen, Sprachen und Paradigmen als modische Aussagen zu behandeln. Es gibt eine Menge Mist da draußen, meistens geschrieben von Fanboys / Fangirls oder Marketingleuten, mit wenig (wenn überhaupt) Wissen und Verständnis für Programmierung. Begriffe wie "besser", "weiterentwickelt" usw. gelten einfach nicht.

Ich lerne am besten anhand von Beispielen, vielleicht könnte jemand zeigen, wie man dieselbe Aufgabe auf eine OOP-Art und dann auf eine funktionale Programmierweise ausführt, um zu verstehen und zu vergleichen, was funktionale Programmierung tut / ist.

Das wäre eine schreckliche Art zu lernen. Funktionale und Objektorientierung sind sehr unterschiedliche Stile, und jedes andere als schrecklich einfache Beispiel würde nicht zu dem einen oder anderen Stil passen.

1 Aber in letzter Zeit versucht, seinen Anwendungsbereich auf generische Programmierung zu erweitern, mal sehen, wie das geht.


Abschließend:

  • Konzentrieren Sie sich darauf, Javascript zu lernen, es ist eine schöne und äußerst nützliche Sprache. Lerne die Sprache, nicht den Hype.
  • Ziemlich viele verschiedene Paradigmen, die alle gleichermaßen nützlich sind. Sie entscheiden selbst, welches Sie bevorzugen und welches am besten zu Ihrem Gebäude passt.
  • Wenn Sie funktionale Programmierung erlernen möchten, wählen Sie eine geeignetere Sprache wie Scheme oder Clojure . Aber Sie müssen zuerst die mathematischen Konzepte verstehen.
  • Recherchiere, bevor du fragst. Die meisten Ihrer Fragen werden durch die entsprechenden Wikipedia-Artikel beantwortet. Zu wissen, wie man recherchiert und fragt, ist eine äußerst wichtige Fähigkeit für jeden Programmierer.
yannis
quelle
5
+1 Tolle Resonanz. Aufgrund der Art und Weise, wie die Programmierausbildung strukturiert ist, scheinen neue Programmierer die Paradigmen für exklusiv und diskret zu halten, aber sie sind es nicht. Versuchen Sie, OOP-Code zu schreiben, der Funktionskonzepte nutzt, wenn dies sinnvoll ist. Ereignisgesteuertes Programmieren ist ein Paradigma, aber Aspekte der EDV beeinflussen sicherlich jedes GUI- und Web-Programm. Polymorphismus , ein Kernmerkmal von OOP, ist eine wirklich generische Programmierung. Die Benennung dieser Ideen hilft uns, eine gute Programmierung zu konzipieren, aber Sie sollten keine verwenden, die andere ausschließt.
Kojiro
Obwohl die ursprüngliche Frage und Ihre Antwort Javascript und dessen Beziehung zur funktionalen Programmierung beschreiben, denke ich, dass Ihre Antwort einer der besseren Vergleiche zwischen OO und funktionaler Programmierung ist, die ich gesehen habe. Gut gemacht.
AnotherDeveloper
„Das wäre eine schreckliche Art zu lernen.“ Ich habe gerade dieses Buch gelesen, das ein Problem darstellt und es mit einer Reihe von Paradigmen löst, einschließlich der OOP- und FP-Stile: github.com/crista/exercises-in-programming-style . Ich habe viel daraus gelernt!
Nick
@nick Das kann dir nur beschreiben, wie das Paradigma aussieht und wie es funktioniert, aber es sagt dir nicht warum , was wohl der wichtigste Aspekt ist. Aber Sie müssen erst lernen, warum :) Manchmal vergessen wir, dass diese Dinge ein Prozess sind.
Matthew Brent
8

Javascript kann als funktionale Sprache verwendet werden, in der Tat macht es das ganz gut. Es ist möglich, Monaden zu implementieren, die Unterstützung für ein Lambda-Konstrukt usw. haben. Es ist nicht ausschließlich eine funktionale Sprache, da es auch viele objektorientierte Merkmale hat, aber auf diese Weise verwendet werden kann. Eigentlich finde ich, dass die Verwendung von Javascript als funktionale Sprache eine großartige Möglichkeit ist, es zu verwenden. (Beispiel jQuery und underscore.js)

Zachary K
quelle
gut und prägnant! Einverstanden, dass funktionale Programmierung oft der einfachste Weg ist, etwas in js zu erledigen.
Mistkerl
Noch interessanter als Monaden ist die Implementierung von Pfeilen mit JS ( cs.umd.edu/projects/PL/arrowlets ). Nun, warum jemand würde wollen Pfeile in JavaScript, das ist eine offene Frage. Aber es kann getan werden.
RTPerson
Ich gebe zu, dass ich nicht genug über Pfeile verstehe, um zu wissen, ob sie nützlich sind. Aber ich arbeite an einem Buch über Monaden in Javascript und kann ein Kapitel über Pfeile hinzufügen ( shop.oreilly.com/product/0636920023890.do )
Zachary K
6

Evolution bedeutet normalerweise eine inkrementelle Veränderung. OOP ist keine inkrementelle Ergänzung der prozeduralen Programmierung - tatsächlich ist es völlig orthogonal zu einem zugrunde liegenden Programmiermodell und kann mit jedem von ihnen kombiniert werden. Funktionale Programmierung ist keine inkrementelle Ergänzung zu prozeduralem, OOP oder was auch immer - sie ist eine alternative Basis zum Ausdrücken grundlegender Rechenprinzipien, und sie ist tatsächlich die erste derartige Basis, die jemals formuliert wurde, lange bevor die ersten Computer aufgetaucht sind. Es ist wichtig zu verstehen, dass alle diese grundlegenden Systeme gleichwertig sind (dh eines kann in Form eines anderen ausgedrückt werden).

Um den funktionalen Ansatz zu verstehen, müssen Sie zuerst die Grundrechenarten erlernen . Wenn Sie ein Gefühl dafür bekommen möchten, was es bedeutet, in JavaScript in einem funktionalen Stil zu codieren , beginnen Sie mit der Verwendung von jQuery .

SK-Logik
quelle
2

Nein.

JavaScript ist in erster Linie eine objektorientierte Sprache.

Das heißt nicht, dass Sie keine JavaScript-Programme in einem funktionalen Stil schreiben können, da Sie einen funktionalen Stil in jeder Turing-Sprache anwenden können, wenn Sie sich anstrengen. Sie können die Funktionsprogrammierung in Assembler durchführen, wenn Sie möchten. Dies macht jedoch nicht jede Sprache funktionsfähig. Genauso gut können Sie Haskell imperative oder Java als logische Programmiersprache bezeichnen - wenn Sie diesen Ansatz wählen, werden die Begriffe bald bedeutungslos.

IMO die Art und Weise, eine Sprache in das entsprechende Paradigma zu klassifizieren, ist zu berücksichtigen:

  • Was ist der dominante Stil, der durch die Sprachkonstrukte ermöglicht wird? (OOP für JavaScript, funktionale Sprachen betonen stattdessen Funktionen und unveränderliche Datenwerte)
  • Welches Paradigma wird in den Kernbibliotheken der Sprache unterstützt?
  • Welche Funktionen sind in der Sprache deaktiviert oder nicht empfohlen? (Funktionssprachen verhindern oder verbieten veränderbare Variablen, was bei JavaScript nicht der Fall ist.)
  • Welcher Entwicklungsstil in der Community der Entwickler, die die Sprache verwenden, vorherrscht (auch hier ist OOP in der JavaScript-Welt eindeutig vorherrschend)

Persönlich finde ich es ziemlich amüsant, dass viele Leute gerne behaupten, eine Sprache sei "funktional", nur weil es im Moment ein Modebegriff ist :-)

Wenn Sie eine etwas lange, aber unterhaltsame Perspektive auf Programmierparadigmen im Laufe der Jahre haben möchten, sollten Sie sich Onkel Bob Martins Video "The Last Programming Language" ansehen . Für mich war die großartige Erkenntnis aus diesem Vortrag, dass Programmierparadigmen durch die Eigenschaften definiert sind, die sie wegnehmen , nicht durch die Eigenschaften, die sie einbauen.

mikera
quelle
What is the dominant style enabled by the language constructsIch wage dich, das auf Perl anzuwenden ... oder auf irgendeinen anderen deiner Punkte, wirklich :)
yannis
2
Perl? Gute Herausforderung! Es ist eine Art Assemblersprache in dem Sinne, dass Sie so ziemlich jedes Paradigma hacken können, das Sie zusammen haben möchten, aber in der allgemeinen Verwendung, die ich gesehen habe (Skripting), wird es hauptsächlich als imperative / prozedurale Sprache verwendet.
Mikera
Nun, oop ist auch ziemlich verbreitet. In gewisser Weise natürlich. Und funktionell auch , wenn auch ungewöhnlich. Perl ist nur Perl, es macht keinen Sinn, einen Sinn daraus zu machen :)
yannis
JavaScript ist etwas funktionaler als Java, da es zumindest Closures und erstklassige Funktionen hat. Aber Sie haben Recht, JavaScript funktioniert genauso gut wie C #.
Raynos
2

Javascript ist in erster Linie prototypisch und verfügt über funktionale Funktionen, die durch die Verwendung von Funktionen als erstklassige Objekte gewährleistet werden.

Dies bedeutet, dass Sie Funktionen als Daten verwenden können, was den merkwürdigen Effekt hat, dass weniger Variablen benötigt werden, die den Status beibehalten. Wenn Sie feststellen, dass Sie nach der var-Anweisung greifen oder eine oder mehrere "if" -Anweisungen verwenden, weichen Sie von einem funktionalen Stil ab.

Eine weitere bemerkenswerte Besonderheit des funktionalen Stils ist, dass Funktionen NUR das Ergebnis ihrer Bewertung zurückgeben sollten und keine Nebenwirkungen auf den Zustand außerhalb ihres Bereichs haben:

// oops, this is producing a side effect
function sideEffecter(){//theres no input...        
    window.thingy = 'foo';
    // hey, this isn't returning anything!!!
} 

Funktionale Sprachen sind nicht destruktiv. Das bedeutet, dass sie die Eingabe nicht mutieren, sondern basierend auf der Eingabe völlig neue Daten zurückgeben. Siehe diesen Thread: https://stackoverflow.com/questions/749084/jquery-map-vs-each

Funktionale Sprachen bieten auch viele Methoden, die gemeinsam sind - mit Namen wie "map", "fold", "reduction", die Listen / Sammlungen verarbeiten. In JS müssen wir diese im Gegensatz zu anderen Sprachen manuell in die Existenz bringen. In Bibliotheken wie underscore.js finden Sie einige Beispiele, obwohl die neueste Implementierung von JS einige davon bereits enthält.

Das Wichtigste, das zu beachten ist (IMO), ist, dass JS zwar einige Funktionsmuster verwenden kann, aber nicht immer gut für die Ausführung geeignet ist.

Nehmen Sie zum Beispiel das Durchlaufen eines Arrays. Sie können dazu einen funktionalen Stil oder die nativen Schleifenkonstrukte verwenden - und im Allgemeinen ist die Schleife performanter. Nehmen Sie dieses Beispiel - schlagen Sie es mit Schleifen zunehmender Größe an und zeichnen Sie die Ausführungszeiten in verschiedenen Browsern auf (das habe ich bereits getan, aber ich habe die Benchmarks verloren - sorry!):

var test = ['foo', 'bar', 'baz'], removeFunc, removeLoop;

//(semi)functional style...
// to be really functional each condition in the ternary would be another function
removeFunc = function(src, trg) {
    return src.length === 0 ? 
        src : 
            src[0] === trg ? 
                src.slice(1) : 
                    [src[0]].concat(removeFunc(src.slice(1), trg));
};

//but this is faster
removeLoop = function(src, trg){
    var len = src.length, // using variables to represent state...
        i=0, 
        result = [];        
    while(i < n){
       if(src[i] !== trg){
          result.push(src[i]);
       }
       i = i+1;
    }
}

Wenn Sie ein funktionales Konstrukt verwenden, um Schleifen von beträchtlicher Größe zu treffen, und keine Form der Ad-hoc-Stapelverwaltung verwenden, können Sie den Stapel überfluten (obwohl Sie fairerweise eine GROSSE Liste benötigen, damit dies auftritt. ..). Sie müssen auch die Variantenoptimierungen in jedem Browser berücksichtigen - obwohl dies offensichtlich eher ein festes Ziel ist, wenn Sie in einer Node.js-Umgebung arbeiten.

Das heißt nicht, dass Sie keine funktionalen Konstrukte in Javascript verwenden sollten - beachten Sie nur die Einschränkungen bei der Implementierung in Bezug auf die Umgebung.

Hier sind einige Links, die für Sie von Interesse sein könnten:

Ein gutes Kapitel über funktionale Programmierung in Javascript aus dem exzellenten "Eloquent Javascript"

Der kleine Schemer

Ein Freund von mir hat eine JS-Bibliothek geschrieben, die auf dem kleinen Schemer basiert

Ein gutes Tutorial zum Schema, das Ihnen helfen könnte, FP besser zu verstehen

sunwukung
quelle