2011-12-12 27 views
5

Me pregunto por qué necesitamos funciones como "% de identidad", que es lo mismo que dejar a = a. ¿Va a mejorar el rendimiento al usarlo?ocaml% función de identidad

Estoy introduciendo la tipificación fantasma en mi programa, llamando a las funciones de identidad muchas veces para convertir tipos, curioso si "% identity" puede reducir un poco la sobrecarga.

Respuesta

10

La función %identity forma parte de la implementación, no es parte del lenguaje OCaml. Le dice al compilador (en esencia) que no hay nada que hacer para cambiar el parámetro de la función a su valor de retorno. En otras palabras, le dice al compilador que siga usando el mismo valor pero cambie su idea del tipo. Si se usa incorrectamente, básicamente anula todas las excelentes garantías de seguridad del sistema de tipo OCaml. Además, por supuesto, no se garantiza que funcione en ninguna otra implementación del lenguaje (incluidas versiones futuras del compilador INRIA).

La capacidad de incorporación del compilador OCaml ya debería garantizar que no se genere código para las funciones de identidad. Así que te recomendaría que simplemente continúes usándolos.

actualización

Para responder a una pregunta no relacionada en los comentarios .... Supongamos que tiene la composición de funciones y la función identidad:

let (<<) f g x = f (g x) 
let id x = x 

entonces aquí están las funciones de añadir los elementos de una lista, para multiplicar los elementos de una lista, y para componer todas las funciones en una lista:

# let sum l = List.fold_right (+) l 0;; 
val sum : int list -> int = <fun> 
# let product l = List.fold_right (*) l 1;; 
val product : int list -> int = <fun> 
# let composition l = List.fold_right (<<) l id;; 
val composition : ('a -> 'a) list -> 'a -> 'a = <fun> 

Ejemplo s:

# sum [2; 3; 5; 7];; 
- : int = 17 
# product [2; 4; 17];; 
- : int = 136 
# let mx = composition [(+) 1; (*) 10];; 
val mx : int -> int = <fun> 
# mx 2;; 
- : int = 21 

El punto es que 0 es la identidad para la adición, 1 para la multiplicación, y id para la composición de función. id es útil todo el tiempo, al igual que 0 y 1 son.

+0

¿Cuándo usamos la función 'identity' (no necesariamente'% identity') normalmente? –

+0

Esto es algo así como preguntar cuando usamos los números 0 y 1. En un lenguaje donde las funciones son valores de primera clase, la función de identidad es útil con mucha frecuencia. –

+0

lo siento, supongo que mi pregunta debería ser como si pudieras darme un caso útil donde 'let f x = x' debería ser o debe ser usado? –

1

El uso de %identity como una primitiva foránea puede reducir la sobrecarga asociada con la evaluación del cierre (fun x -> x) cada vez que se aplica.

El OCaml compiladores especial de los casos los % primitivas: bytecomp/translcore.ml asociados cada uno con un especial incorporado en el nodo AST (en el caso de %identity que se asigna a la Pidentity); los compiladores coinciden en el nodo y simplifican la expresión a la que se aplica. En el caso de que el compilador nativo, las líneas relevantes son:

  • asmcomp/closure.ml líneas 197 y ss .: simplificar %identity aplica a un argumento constante al argumento en sí mismo:

    begin match p with 
        Pidentity -> make_const_int x 
    | Pnegint -> make_const_int (-x) 
    
  • asmcomp/cmmgen.ml línea 1047 y ss .: simplificar %identity como el LHS de una aplicación para evaluar el argumento directamente:

    match p with 
        (* Generic operations *) 
        Pidentity -> 
         transl arg 
    

El compilador de código de bytes tiene reglas de simplificación similares para la primitiva.