2012-05-19 12 views
6

"Introduction to Caml" dice¿Por qué prefiere currying to tuple arguments en OCaml?

Nota, en Caml es mejor usar las definiciones de funciones al curry para las funciones múltiples de argumentos, no tuplas.

al comparar las convenciones de llamada 'a -> 'b -> 'c al .

Al trabajar con SML/NJ me acostumbré a utilizar tipos de tupla para entrada y salida: ('a * 'b) -> ('c * 'd), por lo que el uso de tuplas para expresar múltiples entradas parece simétrico con la forma en que expreso múltiples salidas.

¿Por qué se recomienda el currying para declaraciones de función OCaml sobre argumentos tuple? ¿Es solo la mayor flexibilidad que proporciona el permitir currying/parcial evaluación, o hay algún otro beneficio que se deriva de los detalles de implementación del compilador OCaml?

+2

La elección de currying la mayoría de las funciones en Caml-light y las versiones posteriores se explica en el informe "El experimento ZINC: una implementación económica del lenguaje ML". Una cosa que recuerdo es que con el esquema de evaluación adecuado (descrito en el informe), una función curried no requiere asignación para ser llamado. http://caml.inria.fr/pub/papers/xleroy-zinc.ps.gz –

+0

@PascalCuoq, mientras que una tupla necesita ser asignada, desempaquetada y luego convertida en GC? –

+0

Sí, si la función también está destinada a ser llamada con tuplas preexistentes ('ft'), no hay forma de evitar el hecho de que se debe asignar una tupla temporal efímera' (x, y) 'para aplicar' f' a cuando lo que uno tiene es solo 'x' y' y'. –

Respuesta

2

Sí, es principalmente la comodidad de la notación y la flexibilidad para hacer una aplicación parcial. Las funciones curried son idiomáticas en OCaml, y es probable que el compilador las optimice algo mejor que las funciones tupladas (mientras que los compiladores SML suelen optimizar para tuplas).

Las ventajas de tupling son la simetría argumento/resultado que mencionas (que es especialmente útil al componer funciones) y quizás la familiaridad notacional (al menos para las personas que provienen del mundo no funcional).

1

Algunos comentarios sobre la optimización en OCaml.

En OCaml, noté que las tuplas siempre se asignan al pasarlas como argumento. Incluso si la asignación en el montón primario es rápida en ocaml, por supuesto es más tiempo que no hacer nada. Por lo tanto, cada vez que pasa una tupla como argumento, hay un tiempo dedicado a la asignación y el llenado de la tupla.

Esperaba que el compilador ocaml estuviera optimizando los casos donde no es necesario construir la tupla. Por ejemplo, cuando incorpora la función llamada, solo puede usar los componentes de la tupla y no la propia tupla. Por lo tanto, la tupla podría ser ignorada. Desafortunadamente, en este caso OCaml no elimina la tupla inútil y aún realiza la asignación. Por esta razón, puede no ser una buena idea usar tuplas en secciones críticas de código.

+0

Creo que esto ya no es cierto. ["OCaml es más inteligente de lo que pensaba"] (https://blogs.janestreet.com/ocaml-is-smarter-thani-i-thought/) dice: "Había impedido la creación de líneas, ¡pero todavía no había una asignación! Bueno, resulta que OCaml puede optimizar una función de tupla para obtener los elementos de la tupla pasados ​​a través de registros, que es exactamente lo que sucedió. Y de nuevo, el compilador se dio cuenta de que no se requería ninguna asignación ". –

5

Creo que gran parte de esto es convencional: las funciones de biblioteca estándar en OCaml son al curry, mientras que en ML estándar generalmente no son, excepto para algunas funciones de orden superior. Sin embargo, hay una diferencia horneada en el lenguaje: los operadores (por ejemplo, (*)) se curry en OCaml (por ejemplo, int -> int -> int); mientras que no están ocupados en la norma ML (por ejemplo, op* puede ser (int * int) -> int). Debido a eso, las funciones incorporadas de orden superior (por ejemplo, plegado) también toman una función que está al curry en OCaml y no cursado en ML estándar; eso significa que para que su función funcione con eso, necesita seguir la convención respectiva, y se sigue a partir de ahí.

+1

Buen punto. Hay otra instancia en la que la elección está integrada: constructores de tipos de datos. En SML son tupled, en Haskell están curry. Por extraño que parezca, en OCaml son tupled, que es un poco incompatible con el resto del lenguaje. –

+1

El significado más profundo detrás de los constructores de tipo de datos que se tupla es que una tupla es un constructor de datos de caso especial anónimo. –

Cuestiones relacionadas