with - two years of functional programming in javascript




Ist "Partial Function Application" im Kontext von Javascript falsch? (4)

Ein Freund von mir und ich diskutierten über Curryning und Partial Function-Anwendungen in Javascript, und wir kamen zu sehr unterschiedlichen Schlussfolgerungen, ob beide erreichbar waren. Ich kam auf diese Implementierung von Function.prototype.curry , die die Grundlage unserer Diskussion war:

Function.prototype.curry = function() {
    if (!arguments.length) return this;

    var args = Array.prototype.slice.apply(arguments);
    var mmm_curry = this, args;

    return function() {
        var inner_args = Array.prototype.slice.apply(arguments);
        return mmm_curry.apply(this, args.concat(inner_args));
    }

}

Welches wird wie folgt verwendet:

var vindaloo = function(a, b) {
    return (a + b);
}

var karahi = vindaloo.curry(1);
var masala = karahi(2);
var gulai = karahi(3);

print(masala);
print(other);

Die Ausgabe von wie folgt in Spidermonkey:

$ js curry.js
3
4

Seiner Meinung nach ist es völlig falsch, auf die Funktion karahi , die an die Variable karahi gebunden ist, zu verweisen, da die JavaScript- function primitiv keine partielle Funktionsanwendung unterstützt. Sein Argument war, dass, wenn die vindaloo Funktion vindaloo ist, die Funktion selbst vollständig angewendet wird und eine Schließung zurückgegeben wird, keine "teilweise angewandte Funktion".

Nun, meine Meinung ist, dass, während Javascript selbst keine Unterstützung für die partielle Anwendung in seinen function bietet (anders gesagt, ML oder Haskell), das bedeutet nicht, dass Sie keine Funktion höherer Ordnung der Sprache erstellen können, die fähig ist des Einkapselungskonzepts einer teilweise angewandten Funktion. Außerdem ist der Umfang der Funktion, obwohl sie "angewendet" wird, immer noch an die von ihr zurückgegebene Schließung gebunden, so dass sie "teilweise angewendet" bleibt.

Welches ist richtig?


Die technischen Details sind mir egal - wenn die Semantik gleich bleibt und die Funktion in jeder Hinsicht so wirkt, als wäre sie wirklich eine teilweise angewandte Funktion, wen interessiert das?

Ich war über Dinge so akademisch, aber die Sorge um solche Einzelheiten wird am Ende nicht wirklich erledigt.

Persönlich verwende ich MochiKit ; Es hat eine nette Partial () -Funktion, die bei der Erstellung von solchen hilft. Ich mag es.


Ich denke, es ist völlig in Ordnung, über die Anwendung von Teilfunktionen in JavaScript zu sprechen - wenn es wie eine partielle Anwendung funktioniert, muss es eine sein. Wie sonst würdest du es nennen?

Wie Ihre Curry- Funktion ihr Ziel erreicht, ist nur ein Implementierungsdetail. In ähnlicher Weise könnten wir eine Teilanwendung in der ECMAScript-Spezifikation haben, aber wenn IE sie dann genauso implementieren würde wie Sie, hätten Sie keine Möglichkeit, dies herauszufinden.


Technisch erstellen Sie eine brandneue Funktion, die die ursprüngliche Funktion aufruft. Wenn mein Verständnis von teilweise angewandten Funktionen korrekt ist, ist dies keine teilweise angewandte Funktion. Eine teilweise angewandte Funktion wäre näher daran (beachten Sie, dass dies keine allgemeine Lösung ist):

vindaloo.curry = function(a) {
    return function(b) {
        return a + b;
    };
};

IIUC, wäre dies noch keine teilweise angewandte Funktion. Aber es ist näher. Eine echte partiell angewendete Funktion würde tatsächlich so aussehen, wenn Sie den Code untersuchen können:

function karahi(b) {
    return 1 + b;
};

Ihre ursprüngliche Methode gibt also technisch nur eine Funktion zurück, die an eine Schließung gebunden ist. Die einzige Möglichkeit, eine Funktion in JavaScript wirklich teilweise anzuwenden, besteht darin, die Funktion zu analysieren, die Änderungen zu übernehmen und sie dann über eine eval () -Methode auszuführen.

Ihre Lösung ist jedoch eine gute praktische Anwendung des Konzepts auf JavaScript, also erreicht praktisch das Ziel, auch wenn es technisch nicht exakt ist.


Seiner Meinung nach war dies, weil das Grundelement der Javascript-Funktion nicht nativ "partielle Funktionsanwendung" unterstützt.

Sie können in ES6 ziemlich elegant currying:

> const add = a => b => a + b
> const add10 = add(10)
> [1,2,3].map(add10)
[ 11, 12, 13 ]




functional-programming