functional - javascript programming
¿La "aplicación de función parcial" es un nombre inapropiado en el contexto de Javascript? (5)
Creo que está perfectamente bien hablar sobre la aplicación de funciones parciales en JavaScript, si funciona como una aplicación parcial, entonces debe ser una. ¿De qué otra manera lo nombrarías?
Cómo su función de curry logra su objetivo es solo un detalle de implementación. De manera similar, podríamos tener una aplicación parcial en la especificación ECMAScript, pero cuando IE lo implementaría tal como lo hizo, no tendría forma de averiguarlo.
Un amigo mío y yo estábamos teniendo un debate sobre el currying y la aplicación de funciones parciales en Javascript, y llegamos a conclusiones muy diferentes en cuanto a si alguno de los dos podía lograrse. Se me ocurrió esta implementación de Function.prototype.curry
, que fue la base de nuestra discusión:
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));
}
}
Que se usa de la siguiente manera:
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);
El resultado de esto es el siguiente en Spidermonkey:
$ js curry.js
3
4
Su opinión era que, dado que la primitiva de la function
Javascript no admite nativamente la "aplicación de función parcial", es completamente incorrecto referirse a la función vinculada a la variable karahi
como parcialmente aplicada. Su argumento fue que cuando la función vindaloo
se curry, la función en sí se aplica por completo y se devuelve un cierre, no una "función parcialmente aplicada".
Ahora, mi opinión es que si bien Javascript no proporciona soporte para la aplicación parcial en sus ''primitivas function
'' (a diferencia de, por ejemplo, ML o Haskell), eso no significa que no se pueda crear una función de orden superior del lenguaje que sea capaz de del concepto de encapsulado de una función parcialmente aplicada. Además, a pesar de ser "aplicado", el alcance de la función sigue estando vinculado al cierre devuelto, lo que hace que permanezca "parcialmente aplicado".
¿Cual es correcta?
Debería verificar las funciones de JavaScript de Curried . No me he acostumbrado por completo a su función de curry, pero podría tener tu respuesta.
Editar: Sin embargo, estoy de acuerdo con su evaluación.
Los detalles técnicos no me importan: si la semántica sigue siendo la misma y, para todos los efectos, la función actúa como si realmente fuera una función parcialmente aplicada, ¿a quién le importa?
Solía ser tan académico con respecto a las cosas, pero preocuparme por esos detalles no hace un trabajo real al final.
Personalmente, uso MochiKit ; tiene una bonita función parcial () que ayuda a la creación de tal. Lo amo
Técnicamente estás creando una nueva función que llama a la función original. Entonces, si mi comprensión de las funciones parcialmente aplicadas es correcta, esta no es una función parcialmente aplicada. Una función parcialmente aplicada estaría más cerca de esto (tenga en cuenta que esta no es una solución general):
vindaloo.curry = function(a) {
return function(b) {
return a + b;
};
};
IIUC, esto todavía no sería una función parcialmente aplicada. Pero está más cerca. Una verdadera función parcialmente aplicada se vería así si puedes examinar el código:
function karahi(b) {
return 1 + b;
};
Entonces, técnicamente, su método original es simplemente devolver una función enlazada dentro de un cierre. La única forma en que se me ocurre aplicar parcialmente una función en JavaScript sería analizar la función, aplicar los cambios y luego ejecutarlo a través de un eval ().
Sin embargo, su solución es una buena aplicación práctica del concepto a JavaScript, por lo que prácticamente logra el objetivo, incluso si no es técnicamente exacto.
Su opinión era que, dado que la primitiva de la función Javascript no es compatible nativamente con la "aplicación de función parcial"
Puedes hacer currying en ES6 con bastante elegancia:
> const add = a => b => a + b
> const add10 = add(10)
> [1,2,3].map(add10)
[ 11, 12, 13 ]