2008-09-18 12 views
11

Un amigo mío y yo estábamos teniendo una discusión 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ó con esta aplicación de Function.prototype.curry, que fue la base de nuestra discusión:¿La "Aplicación de función parcial" es un nombre inapropiado en el contexto de Javascript?

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 utiliza 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); 

La salida de los cuales es el siguiente en Mono Araña:

$ js curry.js 
3 
4 

Su opinión es que, dado que la primitiva Javascript function no admite nativamente la "aplicación de función parcial", es completamente incorrecto referirse a la función n vinculado a la variable karahi como parcialmente aplicado. Su argumento fue que cuando la función vindaloo está al curry, la función en sí se aplica completamente 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 pueda crear una función de orden superior del lenguaje que es capaz de encapsular el concepto 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".

¿Cuál es la correcta?

+0

Aviso [la diferencia entre currying y aplicación parcial] (https://en.wikipedia.org/wiki/Currying#Contrast_with_partial_function_application) – Bergi

Respuesta

3

Técnicamente está 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 aplicada parcialmente estaría más cerca de este (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 aplicada parcialmente. Pero está más cerca. Una verdadera función parcialmente aplicada en realidad se vería como esto si se puede examinar el código:

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

Así que, técnicamente, su método original es simplemente el retorno de una función con destino 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 de JavaScript, por lo que prácticamente logra el objetivo, incluso si no es técnicamente exacto.

+0

Usted habla de "técnicamente" frente a "prácticamente", pero ¿qué hay de "teóricamente"? ¿La "aplicación de función parcial" es un concepto teórico o técnico? Si imaginamos la función curry/parcial como una "función conceptual" (no "función Javascript"), ¿no se "aplica parcialmente"? –

+2

Creo que la "aplicación parcial" es una cuestión conceptual, no una cuestión de implementación. –

0

Deberías echar un vistazo a Curried JavaScript Functions. 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.

3

Creo que está perfectamente bien hablar de la aplicación de función parcial en JavaScript - si funciona como una aplicación parcial, entonces debe ser . ¿De qué otra manera lo nombrarías?

Cómo funciona su curry cumple su objetivo es simplemente una implementación detalle. De forma similar, podríamos tener una aplicación parcial en la especificación de ECMAScript, , pero cuando IE lo implemente tal como lo hizo, tendría sin forma de averiguarlo.

1

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 sobre las cosas, pero preocuparse 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

0

Su opinión era que, dado que la función Javascript primitivo no soporta de forma nativa "aplicación de función parcial"

Usted puede hacer currying en ES6 bastante elegante:

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