Entiendo la diferencia entre la aplicación de función parcial y una función currificada ( f(X x Y x Z) -> N
vs f(X -> (Y -> (Z -> N)))
), pero no veo cuál es la consecuencia de esta diferencia al desarrollar software.
Entiendo la diferencia entre la aplicación de función parcial y una función currificada ( f(X x Y x Z) -> N
vs f(X -> (Y -> (Z -> N)))
), pero no veo cuál es la consecuencia de esta diferencia al desarrollar software.
Originalmente, el currículum era simplificar el análisis, en lugar de una técnica de programación práctica; En el cálculo lambda, todas las funciones son unarias. El curry a menudo se usa a nivel de lenguaje por una razón similar: simplificar el modelo computacional.
La aplicación parcial se usa cuando una función útil y con nombre se puede implementar en términos de otra función más general simplemente arreglando un argumento.
Siguen siendo formas distintas, que involucran diferentes partes de la computación. Considerar:
x=>y=>z=>f(x,y)
(y,z)=>f(0,y,z)
Tenga en cuenta que una función currificada no tiene ningún valor vinculado a argumentos y toma los argumentos en un orden específico; una vez que curry una función, no curry el resultado y no cambie el orden en que la función toma argumentos (aunque podría deshacerse de curry y curry para hacerlo). Una función parcial, por el contrario, tiene valores vinculados a argumentos y puede aplicarse parcialmente a lo largo de cualquier argumento restante.
La aplicación de una función currificada está cerca de la aplicación parcial (después de todo, no curry una función y la deja así; en algún momento, la aplicará), que es donde los usos comienzan a cruzarse. Cuando haces esto, el curry es solo el primero de dos pasos hacia una aplicación parcial.
Creo que su pregunta puede reformularse como: ¿por qué los idiomas tienen curry?
Es sobre todo una cuestión de conveniencia:
En Ocaml, puedes codificar
let sum3 x y z = x + y + z;;
let foo xx yy ll = List.map (sum3 xx yy) ll;;
En Scheme deberás hacer explícitamente una función anónima
(define (sum3 x y z) (+ x y z))
(define (foo xx yy ll) (map (lambda (zz) (sum3 xx yy zz)) ll))
Los idiomas con aplicaciones parciales y currículum necesitan prácticamente tener una optimización para evitar crear cierres parciales en todas partes; no desea que la implementación se aplique siempresum3
como si se definiera como
let sum3 x =
fun y ->
(fun z -> x + y + z)
es decir, asignar 2 cierres intermedios cuando se computa sum3 1 2 3
(entendido y analizado como ((sum3 1) 2) 3
...). Desea que la suma se calcule de inmediato.