Caml ( originalmente un acrónimo de Categorical Abstract Machine Language ) es un lenguaje de programación funcional , de alto nivel , de propósito general y multiparadigma que es un dialecto de la familia de lenguajes de programación ML . Caml se desarrolló en Francia en el Instituto Francés de Investigación en Ciencias de la Computación y Automatización (INRIA) y la Escuela Normal Superior (París) (ENS).
Caml es de tipado estático , se evalúa estrictamente y utiliza administración automática de memoria . OCaml , el descendiente principal de Caml, agrega muchas características al lenguaje, incluida una capa de programación orientada a objetos (objeto).
A continuación #
se representa el mensaje de Caml.
Un programa "¡Hola, mundo!" es:
print_endline "¡Hola, mundo!" ;;
Muchas funciones matemáticas, como factorial, se representan de forma más natural en una forma puramente funcional. La siguiente función Caml recursiva y puramente funcional implementa factorial:
deje que rec fact n = si n = 0 entonces 1 de lo contrario n * fact ( n - 1 );;
La función se puede escribir de forma equivalente utilizando la coincidencia de patrones :
deje que rec fact = función | 0 -> 1 | n -> n * fact ( n - 1 );;
Esta última forma es la definición matemática del factorial como una relación de recurrencia.
Tenga en cuenta que el compilador dedujo que el tipo de esta función es , lo que significa que esta función asigna números enteros a números enteros. Por ejemplo, 12! es:int -> int
# hecho 12 ;; - : int = 479001600
Dado que Caml es un lenguaje de programación funcional , es fácil crear y pasar funciones en programas Caml. Esta capacidad tiene muchas aplicaciones. Calcular la derivada numérica de una función es un ejemplo. La siguiente función Caml d
calcula la derivada numérica de una función dada f
en un punto dado x
:
sea d delta f x = ( f ( x + . delta ) - . f ( x - . delta )) /. ( 2 . *. delta );;
Esta función requiere un valor pequeño delta
. Una buena opción para delta es la raíz cúbica de la máquina épsilon . [ cita requerida ] .
El tipo de la función d
indica que asigna a float
a otra función con el tipo . Esto nos permite aplicar argumentos parcialmente. Este estilo funcional se conoce como currying . En este caso, es útil aplicar parcialmente el primer argumento a , para obtener una función más especializada:(float -> float) -> float -> float
delta
d
# sea d = d ( sqrt epsilon_float );; val d : ( float -> float ) -> float -> float = < fun >
Tenga en cuenta que el tipo inferido indica que el reemplazo d
espera una función con el tipo como su primer argumento. Podemos calcular una aproximación numérica a la derivada de at con:float -> float
# d ( fun x -> x *. x *. x -. x -. 1 .) 3 .;; - : float = 26 .
La respuesta correcta es .
La función d
se denomina " función de orden superior " porque acepta otra función ( f
) como argumento. Si se avanza más, se puede crear la derivada (aproximada) de f, aplicando d
y omitiendo el x
argumento:
# sea f' = d ( fun x -> x *. x *. x -. x -. 1 .) ;; val f' : float -> float = < fun >
Los conceptos de funciones currificadas y de orden superior son claramente útiles en los programas matemáticos. Estos conceptos son igualmente aplicables a la mayoría de las demás formas de programación y se pueden utilizar para factorizar el código de forma mucho más agresiva, lo que da como resultado programas más cortos y con menos errores.
La transformada wavelet de Haar 1D de una lista de números de longitud de potencia de dos enteros se puede implementar de manera muy sucinta en Caml y es un excelente ejemplo del uso de coincidencia de patrones sobre listas, tomando pares de elementos ( y ) del frente y almacenando sus sumas y diferencias en las listas y , respectivamente:h1
h2
s
d
# deje que haar l = deje que rec aux l s d = coincida con l , s , d con [ s ], [] , d -> s :: d | [] , s , d -> aux s [] d | h1 :: h2 :: t , s , d -> aux t ( h1 + h2 :: s ) ( h1 - h2 :: d ) | _ -> invalid_arg "haar" en aux l [] [] ;; val haar : int lista -> int lista = < fun >
Por ejemplo:
# pelo [ 1 ; 2 ; 3 ; 4 ; - 4 ; - 3 ; - 2 ; - 1 ];; - : lista int = [ 0 ; 20 ; 4 ; 4 ; - 1 ; - 1 ; - 1 ; - 1 ]
La comparación de patrones permite representar transformaciones complejas de forma clara y concisa. Además, el compilador Caml convierte las comparaciones de patrones en código muy eficiente, lo que a veces da como resultado programas más cortos y rápidos que el código equivalente escrito con una declaración de caso (Cardelli 1984, p. 210).
La primera implementación de Caml fue escrita en Lisp por Ascánder Suárez en 1987 en el Instituto Francés de Investigación en Ciencias de la Computación y Automatización (INRIA). [2]
Su sucesor, Caml Light , fue implementado en C por Xavier Leroy y Damien Doligez , [2] y el original fue apodado "Heavy Caml" debido a sus mayores requisitos de memoria y CPU. [2]
Caml Special Light fue una nueva versión completa que agregó un poderoso sistema de módulos al lenguaje principal. Se amplió con una capa de programación orientada a objetos (objeto) para convertirse en Objective Caml , que luego pasó a llamarse OCaml .