stringtranslate.com

OCaml

OCaml ( / ˈ k æ m əl / oh- KAM -əl , anteriormente Objective Caml ) es un lenguaje de programación multiparadigma de alto nivel y propósito general que extiende el dialecto Caml de ML con características orientadas a objetos . OCaml fue creado en 1996 por Xavier Leroy , Jérôme Vouillon, [5] Damien Doligez , Didier Rémy, [6] Ascánder Suárez y otros.

La cadena de herramientas OCaml incluye un intérprete interactivo de nivel superior , un compilador de bytecode , un compilador de código nativo optimizador , un depurador reversible y un administrador de paquetes (OPAM). OCaml se desarrolló inicialmente en el contexto de la demostración automatizada de teoremas y se utiliza en análisis estático y software de métodos formales . Más allá de estas áreas, se ha utilizado en programación de sistemas , desarrollo web y utilidades financieras específicas, entre otros dominios de aplicación.

El acrónimo CAML originalmente significaba Categorical Abstract Machine Language (Lenguaje de máquina abstracto categórico ), pero OCaml omite esta máquina abstracta . [7] OCaml es un proyecto de software libre y de código abierto administrado y mantenido principalmente por el Instituto Francés de Investigación en Ciencias de la Computación y Automatización (Inria). A principios de la década de 2000, muchos lenguajes adoptaron elementos de OCaml, en particular F# y Scala .

Filosofía

Los lenguajes derivados de ML son más conocidos por sus sistemas de tipos estáticos y compiladores de inferencia de tipos . OCaml unifica la programación funcional , imperativa y orientada a objetos bajo un sistema de tipos similar a ML. Por lo tanto, los programadores no necesitan estar muy familiarizados con el paradigma del lenguaje funcional puro para usar OCaml.

Al exigir al programador que trabaje dentro de las limitaciones de su sistema de tipos estáticos , OCaml elimina muchos de los problemas de ejecución relacionados con los tipos asociados con los lenguajes de tipado dinámico . Además, el compilador de inferencia de tipos de OCaml reduce en gran medida la necesidad de las anotaciones de tipos manuales que se requieren en la mayoría de los lenguajes de tipado estático. Por ejemplo, los tipos de datos de las variables y las firmas de las funciones normalmente no necesitan declararse explícitamente, como ocurre en lenguajes como Java y C# , porque se pueden inferir a partir de los operadores y otras funciones que se aplican a las variables y otros valores en el código. El uso eficaz del sistema de tipos de OCaml puede requerir cierta sofisticación por parte de un programador, pero esta disciplina se ve recompensada con un software confiable y de alto rendimiento.

OCaml se distingue quizás más de otros lenguajes con orígenes académicos por su énfasis en el rendimiento. Su sistema de tipos estáticos evita las discrepancias de tipos en tiempo de ejecución y, por lo tanto, evita las comprobaciones de seguridad y de tipos en tiempo de ejecución que afectan al rendimiento de los lenguajes tipados dinámicamente, al tiempo que garantiza la seguridad en tiempo de ejecución, excepto cuando la comprobación de límites de matriz está desactivada o cuando se utilizan algunas características de tipo inseguro como la serialización . Estos son lo suficientemente raros como para que evitarlos sea bastante posible en la práctica.

Aparte de la sobrecarga de verificación de tipos, los lenguajes de programación funcional son, en general, difíciles de compilar para obtener un código de lenguaje de máquina eficiente, debido a problemas como el problema funarg . Junto con las optimizaciones estándar de bucles, registros e instrucciones, el compilador optimizador de OCaml emplea métodos de análisis de programas estáticos para optimizar el encasillamiento de valores y la asignación de cierres , lo que ayuda a maximizar el rendimiento del código resultante incluso si hace un uso extensivo de construcciones de programación funcional.

Xavier Leroy ha afirmado que "OCaml ofrece al menos el 50% del rendimiento de un compilador de C decente", [8] aunque una comparación directa es imposible. Algunas funciones en la biblioteca estándar de OCaml se implementan con algoritmos más rápidos que las funciones equivalentes en las bibliotecas estándar de otros lenguajes. Por ejemplo, la implementación de la unión de conjuntos en la biblioteca estándar de OCaml en teoría es asintóticamente más rápida que la función equivalente en las bibliotecas estándar de lenguajes imperativos (por ejemplo, C++, Java) porque la implementación de OCaml puede explotar la inmutabilidad de los conjuntos para reutilizar partes de los conjuntos de entrada en la salida (ver estructura de datos persistentes ).

Historia

El equipo de desarrollo de OCaml recibe un premio en el Simposio sobre Principios de Lenguajes de Programación (POPL) 2024

Desarrollo de ML (Metalenguaje)

Entre los años 1970 y 1980, Robin Milner , un científico informático británico y ganador del premio Turing , trabajó en el Laboratorio de Fundamentos de la Informática de la Universidad de Edimburgo . [9] [10] Milner y otros estaban trabajando en demostradores de teoremas , que históricamente se desarrollaron en lenguajes como Lisp . Milner se topó repetidamente con el problema de que los demostradores de teoremas intentarían afirmar que una prueba era válida juntando pruebas no válidas. [10] Como resultado, continuó desarrollando el metalenguaje para su Logic for Computable Functions , un lenguaje que solo permitiría al escritor construir pruebas válidas con su sistema de tipos polimórficos. [11] ML se convirtió en un compilador para simplificar el uso de LCF en diferentes máquinas y, en la década de 1980, se convirtió en un sistema completo propio. [11] ML eventualmente serviría como base para la creación de OCaml.

A principios de la década de 1980, hubo algunos desarrollos que impulsaron al equipo Formel de INRIA a interesarse en el lenguaje ML. Luca Cardelli , profesor de investigación de la Universidad de Oxford , utilizó su máquina abstracta funcional para desarrollar una implementación más rápida de ML, y Robin Milner propuso una nueva definición de ML para evitar la divergencia entre varias implementaciones. Simultáneamente, Pierre-Louis Curien, investigador sénior de la Universidad Paris Diderot , desarrolló un cálculo de combinadores categóricos y lo vinculó al cálculo lambda , lo que condujo a la definición de la máquina abstracta categórica (CAM). Guy Cousineau, investigador de la Universidad Paris Diderot, reconoció que esto podría aplicarse como un método de compilación para ML. [12]

Primera implementación

Caml fue diseñado y desarrollado inicialmente por el equipo Formel de INRIA, encabezado por Gérard Huet . La primera implementación de Caml se creó en 1987 y se siguió desarrollando hasta 1992. Aunque estuvo encabezado por Ascánder Suárez, Pierre Weis y Michel Mauny continuaron con el desarrollo después de que él se fuera en 1988. [12]

Guy Cousineau recuerda que su experiencia en la implementación de lenguajes de programación fue muy limitada al principio y que había múltiples deficiencias de las que era responsable. A pesar de esto, cree que "Ascander, Pierre y Michel hicieron un buen trabajo". [12]

Luz de Caml

Entre 1990 y 1991, Xavier Leroy diseñó una nueva implementación de Caml basada en un intérprete de bytecode escrito en C. Además de esto, Damien Doligez escribió un sistema de gestión de memoria, también conocido como recolector de basura secuencial , para esta implementación. [11] Esta nueva implementación, conocida como Caml Light , reemplazó a la antigua implementación de Caml y se ejecutó en pequeñas máquinas de escritorio. [12] En los años siguientes, aparecieron bibliotecas como las herramientas de manipulación de sintaxis de Michel Mauny y ayudaron a promover el uso de Caml en equipos educativos y de investigación. [11]

Luz especial Caml

En 1995, Xavier Leroy lanzó Caml Special Light, que era una versión mejorada de Caml. [12] Se agregó un compilador de código nativo optimizador al compilador de bytecode, lo que aumentó en gran medida el rendimiento a niveles comparables con lenguajes convencionales como C++ . [11] [12] Además, Leroy diseñó un sistema de módulos de alto nivel inspirado en el sistema de módulos de Standard ML que proporcionaba potentes facilidades para la abstracción y la parametrización y facilitaba la construcción de programas a gran escala. [11]

Objetivo Caml

Didier Rémy y Jérôme Vouillon diseñaron un sistema de tipos expresivos para objetos y clases, que se integró en Caml Special Light. Esto condujo al surgimiento del lenguaje Objective Caml, lanzado por primera vez en 1996 y posteriormente renombrado como OCaml en 2011. Este sistema de objetos admitía notablemente muchos modismos orientados a objetos predominantes de una manera estáticamente segura para los tipos, mientras que esos mismos modismos causaban problemas o requerían verificaciones en tiempo de ejecución en lenguajes como C++ o Java . En 2000, Jacques Garrigue amplió Objective Caml con múltiples características nuevas, como métodos polimórficos, variantes y argumentos etiquetados y opcionales. [11] [12]

Desarrollo continuo

Se han agregado mejoras al lenguaje de manera incremental durante las últimas dos décadas para respaldar las crecientes bases de código comerciales y académicas en OCaml. [11] La versión OCaml 4.0 en 2012 agregó tipos de datos algebraicos generalizados (GADT) y módulos de primera clase para aumentar la flexibilidad del lenguaje. [11] La versión OCaml 5.0.0 en 2022 [13] es una reescritura completa del entorno de ejecución del lenguaje, que elimina el bloqueo GC global y agrega controladores de efectos a través de continuaciones delimitadas . Estos cambios permiten la compatibilidad con el paralelismo de memoria compartida y la concurrencia daltónica, respectivamente.

El desarrollo de OCaml continuó dentro del equipo Cristal en INRIA hasta 2005, cuando fue reemplazado por el equipo Gallium. [14] Posteriormente, Gallium fue reemplazado por el equipo Cambium en 2019. [15] [16] A partir de 2023, hay 23 desarrolladores principales de la distribución del compilador de una variedad de organizaciones [17] y 41 desarrolladores para el ecosistema más amplio de herramientas y empaquetado de OCaml. [18]

Características

OCaml presenta un sistema de tipos estáticos , inferencia de tipos , polimorfismo paramétrico , recursión de cola , coincidencia de patrones , cierres léxicos de primera clase , functores (módulos paramétricos) , manejo de excepciones , manejo de efectos y recolección de basura automática generacional incremental .

OCaml se destaca por extender la inferencia de tipos de estilo ML a un sistema de objetos en un lenguaje de propósito general. Esto permite la subtipificación estructural , donde los tipos de objetos son compatibles si sus firmas de método son compatibles, independientemente de su herencia declarada (una característica inusual en lenguajes tipados estáticamente).

Se proporciona una interfaz de funciones externas para vincular a primitivas de C , incluido soporte de lenguaje para matrices numéricas eficientes en formatos compatibles con C y Fortran . OCaml también admite la creación de bibliotecas de funciones de OCaml que se pueden vincular a un programa principal en C, de modo que se pueda distribuir una biblioteca de OCaml a programadores de C que no tengan conocimiento o instalación de OCaml.

La distribución de OCaml contiene:

El compilador de código nativo está disponible para muchas plataformas, incluidas Unix , Microsoft Windows y Apple macOS . La portabilidad se logra mediante la compatibilidad con la generación de código nativo para las principales arquitecturas:

El compilador de bytecode admite el funcionamiento en cualquier arquitectura de 32 o 64 bits cuando la generación de código nativo no está disponible y solo requiere un compilador de C.

Los programas de código nativo y bytecode de OCaml se pueden escribir en un estilo multiproceso , con cambio de contexto preventivo. Los subprocesos de OCaml en el mismo dominio [20] se ejecutan solo mediante tiempo compartido. Sin embargo, un programa de OCaml puede contener varios dominios.

Ejemplos de código

Los fragmentos de código OCaml se estudian más fácilmente si se introducen en el REPL de nivel superior . Se trata de una sesión OCaml interactiva que imprime los tipos inferidos de las expresiones resultantes o definidas. [21] El nivel superior de OCaml se inicia simplemente ejecutando el programa OCaml:

$ ocaml  Objetivo Caml versión 3.09.0 #

Luego se puede ingresar el código en el mensaje "#". Por ejemplo, para calcular 1+2*3:

# 1  + 2 * 3 ;; - : int = 7   

OCaml infiere que el tipo de expresión es "int" (un entero con precisión de máquina ) y da el resultado "7".

Hola Mundo

El siguiente programa "hello.ml":

print_endline  "¡Hola mundo!"

se puede compilar en un ejecutable de bytecode:

$ ocamlc hola.ml -o hola

o compilado en un ejecutable de código nativo optimizado:

$ ocamlopt hola.ml -o hola

y ejecutado:

$ ./hello ¡Hola mundo! $

El primer argumento de ocamlc, "hello.ml", especifica el archivo fuente a compilar y el indicador "-o hello" especifica el archivo de salida. [22]

Opción

El optionconstructor de tipos en OCaml, similar al Maybetipo en Haskell , aumenta un tipo de datos dado para devolver Someun valor del tipo de datos dado o para devolver None. [23] Esto se utiliza para expresar que un valor podría o no estar presente.

#  Algunos  42 ;; -  :  int  opción  =  Algunos  42 #  Ninguno ;; -  :  ' una  opción  =  Ninguno

Este es un ejemplo de una función que extrae un int de una opción, si hay uno adentro, y lo convierte en una cadena , o si no, devuelve una cadena vacía:

deje que  extraiga  o  =  coincida con  o  con  |  Algún  i  ->  cadena_de_int  i  |  Ninguno  ->  "" ;;
#extraer  ( Algunos 42 );; - : cadena = " 42 "  #extraerNinguno ;; - : cadena = " "           

Sumar una lista de números enteros

Las listas son uno de los tipos de datos fundamentales en OCaml. El siguiente ejemplo de código define una función recursiva sum que acepta un argumento, entires , que se supone que es una lista de enteros. Tenga en cuenta la palabra clave recque indica que la función es recursiva. La función itera recursivamente sobre la lista de enteros dada y proporciona una suma de los elementos. La declaración match tiene similitudes con el elemento switch de C , aunque es mucho más general.

deje que  rec  sume  enteros  =  (* La palabra clave rec significa 'recursivo'. *)  coincide con  enteros  con  |  []  ->  0  (* Resultado 0 si enteros es la lista vacía  []. *)  |  primero  ::  resto  ->  primero  +  suma  resto ;;  (* Llamada recursiva si enteros es una  lista no vacía; primero es el primer  elemento de la lista y resto es una  lista del resto de los elementos,  posiblemente []. *)
 #  suma  [ 1 ; 2 ; 3 ; 4 ; 5 ];;  -  :  int  =  15

Otra forma es utilizar la función de plegado estándar que funciona con listas.

deje  que suma  enteros  =  List . fold_left  ( fun  acumulador  x  ->  acumulador  +  x )  0  enteros ;;
 #  suma  [ 1 ; 2 ; 3 ; 4 ; 5 ];;  -  :  int  =  15

Dado que la función anónima es simplemente la aplicación del operador +, esto se puede abreviar a:

sea  ​​suma  de enteros  =  List . fold_left  (+)  0  enteros

Además, se puede omitir el argumento de lista haciendo uso de una aplicación parcial :

sea  ​​suma  =  Lista . fold_left  (+)  0

Ordenación rápida

OCaml se presta a expresar algoritmos recursivos de forma concisa. El siguiente ejemplo de código implementa un algoritmo similar a quicksort que ordena una lista en orden creciente.

 deje que  rec  qsort  =  función  |  []  ->  []  |  pivote  ::  resto  ->  deje que  sea_menos  x  =  x  <  pivote  en  deje que sea_menos  izquierda ,  derecha  =  Lista . partición  sea_menos  resto  en  qsort  izquierda  @  [ pivote ]  @  qsort  derecha

O utilizando la aplicación parcial del operador >=.

 deje que  rec  qsort  =  función  |  []  ->  []  |  pivote  ::  resto  ->  deje  que sea_menos  =  (>=)  pivote  en  deje que sea_menos  izquierda ,  derecha  =  Lista . partición  sea_menos  resto  en  qsort  izquierda  @  [ pivote ]  @  qsort  derecha

Problema de cumpleaños

El siguiente programa calcula el menor número de personas en una sala para quienes la probabilidad de cumpleaños completamente únicos es menor al 50% (el problema del cumpleaños , donde para 1 persona la probabilidad es 365/365 (o 100%), para 2 es 364/365, para 3 es 364/365 × 363/365, etc.) (respuesta = 23).

sea  ​​year_size  =  365 .deje que  rec  birthday_paradox  prob  personas  =  deje que  prob  =  ( year_size  -.  float personas  ) /  .  year_size  *.  prob  in  si  prob  <  0. 5 entonces Printf . printf "respuesta = %d \n " ( personas + 1 ) de lo contrario birthday_paradox prob ( personas + 1 ) ;;        paradoja_del_cumpleaños  1 . 0  1

Números de la iglesia

El código siguiente define una codificación Church de números naturales , con sucesor (succ) y adición (add). Un numeral Church nes una función de orden superior que acepta una función fy un valor xy se aplica fa tiempos xexactos n. Para convertir un numeral Church de un valor funcional a una cadena, le pasamos una función que antepone la cadena "S"a su entrada y la constante string "0".

sea  ​​cero  f  x  =  x sea  succ  n  f  x  =  f  ( n  f  x ) sea  uno  =  succ  cero sea  dos  =  succ  ( succ  cero ) sea  sumar  n1  n2  f  x  =  n1  f  ( n2  f  x ) sea  to_string  n  =  n  ( fun  k  ->  "S"  ^  k )  "0" sea  _  =  to_string  ( add  ( succ  dos )  dos )

Función factorial de precisión arbitraria (bibliotecas)

Se puede acceder directamente a una variedad de bibliotecas desde OCaml. Por ejemplo, OCaml tiene una biblioteca incorporada para aritmética de precisión arbitraria . Como la función factorial crece muy rápidamente, rápidamente desborda los números de precisión de máquina (normalmente de 32 o 64 bits). Por lo tanto, factorial es un candidato adecuado para la aritmética de precisión arbitraria.

En OCaml, el módulo Num (ahora reemplazado por el módulo ZArith) proporciona aritmética de precisión arbitraria y se puede cargar en un nivel superior en ejecución usando:

#  # usa  "topfind" ;; #  # requiere  "num" ;; #  abre  Num ;;

La función factorial puede entonces escribirse utilizando los operadores numéricos de precisión arbitraria =/ , */ y -/  :

#  deje que  rec  fact  n  =  si  n  =/  Int  0  entonces  Int  1 de lo  contrario  n  */  fact ( n  -/  Int  1 );; val  fact  :  Num . num  ->  Num . num  =  < fun >

Esta función puede calcular factoriales mucho más grandes, como 120!:

#  cadena_de_num  ( hecho  ( Int  120 ));; -  :  cadena  = "6689502913449127057588118054090372586752746333138029810295671352301633 55724496298936687416527198498130815763789321409055253440858940812185989 8481114389650005964960521256960000000000000000000000000000000"

Triángulo (gráficos)

El siguiente programa renderiza un triángulo giratorio en 2D usando OpenGL :

dejar  ()  =  ignorar  ( Glut . init  Sys . argv );  Glut . initDisplayMode  ~ double_buffer : true  () ;  ignorar  ( Glut . createWindow  ~ título : "Demostración de OpenGL" );  dejar  ángulo  t  =  10 .  * .  t  * .  t  en  dejar  render  ()  =  GlClear . clear  [  ` color  ];  GlMat . load_identity  () ;  GlMat . rotate  ~ ángulo :  ( ángulo  ( Sys . time  () ))  ~ z : 1 .  () ;  GlDraw . comienza  ` triángulos ;  Lista . iter  GlDraw . vertex2  [- 1 .,  - 1 .;  0 .,  1 .;  1 .,  - 1 .];  GlDraw . ends  () ;  Glut . swapBuffers  ( )  en  GlMat.modo ` modelview ; Glut.displayFunc ~ cb : render ; Glut.idleFunc ~ cb : ( Algunos Glut.postRedisplay ) ; Glut.mainLoop ( )        

Se requieren los enlaces de LabGL a OpenGL. Luego, el programa se puede compilar en código de bytes con:

$ ocamlc -I +lablGL lablglut.cma lablgl.cma simple.ml -o simple

o a nativecode con:

$ ocamlopt -I +lablGL lablglut.cmxa lablgl.cmxa simple.ml -o simple

o, más simplemente, usando el comando de compilación ocamlfind

$ ocamlfind opt simple.ml -paquete lablgl.glut -linkpkg -o simple

y corre:

$ ./simple

En OCaml se pueden desarrollar programas gráficos 2D y 3D mucho más sofisticados y de alto rendimiento. Gracias al uso de OpenGL y OCaml, los programas resultantes pueden ser multiplataforma y compilarse sin cambios en muchas plataformas importantes.

Secuencia de Fibonacci

El código siguiente calcula la secuencia de Fibonacci de un número n ingresado. Utiliza recursión de cola y coincidencia de patrones.

sea  ​​fib  n  =  sea  rec  fib_aux  m  a  b  =  coincida  m  con  |  0  ->  a  |  _  ->  fib_aux  ( m  -  1 )  b  ( a  +  b )  en  fib_aux  n  0  1

Funciones de orden superior

Las funciones pueden tomar funciones como entrada y devolver funciones como resultado. Por ejemplo, si se aplica f dos veces a una función , se obtiene una función que aplica f dos veces a su argumento.

sea  ​​dos veces  ( f  :  ' a  ->  ' a )  =  fun  ( x  :  ' a )  ->  f  ( f  x );; sea  inc  ( x  :  int )  :  int  =  x  +  1 ;; sea  add2  =  dos veces  inc ;; sea  inc_str  ( x  :  cadena )  :  cadena  =  x  ^  " "  ^  x ;; sea  add_str  =  dos veces ( inc_str );;
 #  add2  98 ;;  -  :  int  =  100 # add_str "Prueba" ;; - : string = "Prueba Prueba Prueba Prueba"        

La función twice utiliza una variable de tipo 'a para indicar que se puede aplicar a cualquier función f que mapee un tipo ' a a sí misma, en lugar de solo a funciones int->int . En particular, twice se puede aplicar incluso a sí misma.

 #  sea  cuatro veces  f  =  ( dos veces  dos veces )  f ;;  val  cuatro veces  :  ( ' a  ->  ' a )  ->  ' a  ->  ' a  =  < fun > # sea sumar4 = cuatro veces inc ;; val sumar4 : int -> int = < fun > # sumar4 98 ;; - : int = 102                      

Lenguas derivadas

MetaOCaml

MetaOCaml [24] es una extensión de programación de múltiples etapas de OCaml que permite la compilación incremental de nuevo código de máquina durante el tiempo de ejecución. En algunas circunstancias, es posible lograr importantes aumentos de velocidad mediante la programación de múltiples etapas, porque hay información más detallada sobre los datos a procesar disponible en el tiempo de ejecución que en el tiempo de compilación normal, por lo que el compilador incremental puede optimizar muchos casos de verificación de condiciones, etc.

A modo de ejemplo: si en tiempo de compilación se sabe que a menudo se necesita alguna función de potencia , pero el valor de se conoce solo en tiempo de ejecución, se puede utilizar una función de potencia de dos etapas en MetaOCaml:x -> x^nn

sea  ​​rec  potencia  n  x  =  si  n  =  0  entonces  .< 1 >.  de lo contrario  si  es par  n  entonces  sqr  ( potencia  ( n / 2 )  x )  de lo contrario  .<.~ x  *.  .~( potencia  ( n  -  1 )  x )>.

Una vez que nse conoce el tiempo de ejecución, se puede crear una función de potencia especializada y muy rápida:

.< fun  x  ->  .~( potencia  5  .< x >.)>.

El resultado es:

diversión  x_1  ->  ( x_1  *  sea  y_3  =  sea  y_2  =  ( x_1  *  1 )  en  ( y_2  *  y_2 )  en  ( y_3  *  y_3 ))

La nueva función se compila automáticamente.

Otros idiomas derivados

Software escrito en OCaml

Usuarios

Al menos varias docenas de empresas utilizan OCaml en algún grado. [30] Algunos ejemplos notables incluyen:

Referencias

  1. ^ "Módulos" . Consultado el 22 de febrero de 2020 .
  2. ^ Leroy, Xavier (1996). "Objetivo Caml 1.00". Lista de correo caml-list.
  3. ^ "Notas de la versión de OCaml 5.2.0" . Consultado el 24 de mayo de 2024 .
  4. ^ "Influencias - La referencia de Rust". La referencia de Rust . Consultado el 31 de diciembre de 2023 .
  5. ^ "Jérôme Vouillon". www.irif.fr. ​Consultado el 14 de junio de 2024 .
  6. ^ "Didier Remy". pauillac.inria.fr . Consultado el 14 de junio de 2024 .
  7. ^ "Una historia de OCaml" . Consultado el 24 de diciembre de 2016 .
  8. ^ Noticias semanales de Linux.
  9. ^ "AJ Milner - Ganador del premio AM Turing". amturing.acm.org . Consultado el 6 de octubre de 2022 .
  10. ^ ab Clarkson, Michael; et al. "1.2. OCaml: Programación funcional en OCaml". courses.cs.cornell.edu . Consultado el 6 de octubre de 2022 .
  11. ^ abcdefghi "Prólogo - OCaml en el mundo real". dev.realworldocaml.org . Consultado el 6 de octubre de 2022 .
  12. ^ abcdefg "Una historia de OCaml – OCaml". v2.ocaml.org . Consultado el 7 de octubre de 2022 .
  13. ^ "Lanzamiento del paquete OCaml 5.0.0 OCaml". OCaml . Consultado el 16 de diciembre de 2022 .
  14. ^ "Projet Cristal". cristal.inria.fr . Consultado el 7 de octubre de 2022 .
  15. ^ "Equipo Gallium - Inicio". gallium.inria.fr . Consultado el 7 de octubre de 2022 .
  16. ^ "Inicio". cambium.inria.fr . Consultado el 7 de octubre de 2022 .
  17. ^ "Gobernanza y membresía del compilador OCaml". 2023.
  18. ^ "Gobernanza y proyectos de OCaml". 2023.
  19. ^ "ocaml/asmcomp en trunk · ocaml/ocaml · GitHub". GitHub . Consultado el 2 de mayo de 2015 .
  20. ^ Un dominio es una unidad de paralelismo en OCaml, un dominio generalmente corresponde a un núcleo de CPU
  21. ^ "OCaml - El sistema de nivel superior o REPL (ocaml)". ocaml.org . Consultado el 17 de mayo de 2021 .
  22. ^ "OCaml - Compilación por lotes (Ocamlc)".
  23. ^ "3.7. Opciones - Programación OCaml: Correcta + Eficiente + Hermosa". cs3110.github.io . Consultado el 7 de octubre de 2022 .
  24. ^ oleg-at-okmij.org. "BER MetaOCaml". okmij.org .
  25. ^ EasyCrypt/easycrypt, EasyCrypt, 5 de julio de 2024 , consultado el 5 de julio de 2024
  26. ^ "Messenger.com ahora está convertido en un 50 % a Reason · Reason". reasonml.github.io . Consultado el 27 de febrero de 2018 .
  27. ^ "Flow: un verificador de tipos estáticos para JavaScript". Flow . Archivado desde el original el 8 de abril de 2022 . Consultado el 10 de febrero de 2019 .
  28. ^ "Inferir analizador estático". Inferir .
  29. ^ "WebAssembly/spec: especificación de WebAssembly, intérprete de referencia y conjunto de pruebas". World Wide Web Consortium . 5 de diciembre de 2019 . Consultado el 14 de mayo de 2021 – a través de GitHub.
  30. ^ "Empresas que utilizan OCaml". OCaml.org . Consultado el 14 de mayo de 2021 .
  31. ^ "BuckleScript: ¡La versión 1.0 ha llegado! | Tecnología en Bloomberg". Tecnología en Bloomberg . 8 de septiembre de 2016 . Consultado el 21 de mayo de 2017 .
  32. ^ Scott, David; Sharp, Richard; Gazagnaire, Thomas; Madhavapeddy, Anil (2010). Uso de programación funcional dentro de un grupo de productos industriales: perspectivas y percepciones. Conferencia internacional sobre programación funcional . Association for Computing Machinery . doi :10.1145/1863543.1863557.
  33. ^ "Flujo en GitHub". GitHub . 2023.
  34. ^ Yaron Minsky (1 de noviembre de 2011). "OCaml for the Masses" (OCaml para las masas) . Consultado el 2 de mayo de 2015 .
  35. ^ Yaron Minsky (2016). "Keynote - Observaciones de un programador funcional". Usos comerciales de la programación funcional en ACM .
  36. ^ Yaron Minsky (2023). "Señales e hilos" (Podcast). Jane Street Capital .
  37. ^ Anil Madhavapeddy (2016). "Mejora de Docker con Unikernels: presentación de HyperKit, VPNKit y DataKit". Docker, Inc.
  38. ^ "VPNKit en GitHub". GitHub . 2023.

Enlaces externos