stringtranslate.com

OCaml

OCaml ( / ˈ k æ m əl / oh- KAM -əl , anteriormente Objective Caml ) es un lenguaje de programación multiparadigma , de alto nivel y de 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, Damien Doligez , Didier Rémy, Ascander Suárez y otros.

La cadena de herramientas OCaml incluye un intérprete interactivo de nivel superior , un compilador de código de bytes , un compilador de código nativo de optimización, 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 software de análisis estático y métodos formales . Más allá de estas áreas, ha encontrado uso en programación de sistemas , desarrollo web y utilidades financieras específicas, entre otros dominios de aplicaciones.

El acrónimo CAML originalmente significaba Lenguaje de máquina abstracto categórico , pero OCaml omite esta máquina abstracta . [5] OCaml es un proyecto de software gratuito y de código abierto gestionado y mantenido principalmente por el Instituto Francés de Investigación en Informática 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 mejor 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 utilizar OCaml.

Al requerir que el programador trabaje dentro de las limitaciones de su sistema de tipos estáticos, OCaml elimina muchos de los problemas de tiempo de ejecución relacionados con los tipos asociados con los lenguajes escritos dinámicamente . Además, el compilador de inferencia de tipos de OCaml reduce en gran medida la necesidad de anotaciones de tipo manuales que se requieren en la mayoría de los lenguajes de tipo estático. Por ejemplo, normalmente no es necesario declarar explícitamente los tipos de datos de las variables y las firmas de las funciones, como ocurre en lenguajes como Java y C# , porque pueden inferirse 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 quizás se distinga más de otros lenguajes con orígenes académicos por su énfasis en el rendimiento. Su sistema de tipos estáticos evita discrepancias entre los tipos de tiempo de ejecución y, por lo tanto, evita las comprobaciones de seguridad y de tipos de tiempo de ejecución que sobrecargan el rendimiento de los lenguajes escritos dinámicamente, al mismo tiempo que garantiza la seguridad del tiempo de ejecución, excepto cuando la verificación de límites de matriz está desactivada o cuando se utilizan algunas funciones de tipo no seguro, como la serialización . . Estos son lo suficientemente raros como para evitarlos en la práctica.

Aparte de la sobrecarga de verificación de tipos, los lenguajes de programación funcionales son, en general, difíciles de compilar en 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 de optimización de OCaml emplea métodos de análisis de programas estáticos para optimizar la asignación de valores y cierres , lo que ayuda a maximizar el rendimiento del código resultante incluso si hace un uso extensivo de construcciones de programación funcionales.

Xavier Leroy ha declarado que "OCaml ofrece al menos el 50% del rendimiento de un compilador de C decente", [6] aunque una comparación directa es imposible. Algunas funciones de la biblioteca estándar OCaml se implementan con algoritmos más rápidos que 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 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 OCaml puede explotar la inmutabilidad de los conjuntos para reutilizar partes de conjuntos de entrada en la salida (ver estructura de datos persistentes ).

Historia

Desarrollo de ML (Metalenguaje)

Entre los años 1970 y 1980, Robin Milner , un informático británico y ganador del Premio Turing , trabajó en el Laboratorio de Fundamentos de la Informática de la Universidad de Edimburgo . [7] [8] 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 reuniendo pruebas que no eran válidas. [8] Como resultado, pasó a desarrollar el metalenguaje para su Lógica para funciones computables , un lenguaje que solo permitiría al escritor construir pruebas válidas con su sistema de tipos polimórficos. [9] 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 en sí mismo. [9] ML eventualmente serviría como base para la creación de OCaml.

A principios de la década de 1980, hubo algunos desarrollos que llevaron al equipo Formel de INRIA a interesarse en el lenguaje ML. Luca Cardelli , profesor de investigación en 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 divergencias entre varias implementaciones. Simultáneamente, Pierre-Louis Curien, investigador principal 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 técnica de compilación para ML. [10]

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 desarrolló hasta 1992. Aunque fue encabezada por Ascander Suárez, Pierre Weis y Michel Mauny continuaron con el desarrollo después de que él se fue en 1988. [10]

Se cita a Guy Cousineau recordando que su experiencia con la implementación de lenguajes de programación fue inicialmente muy limitada y que había múltiples deficiencias de las que él es responsable. A pesar de ello, considera que "Ascander, Pierre y Michel hicieron un trabajo bastante bonito". [10]

Luz de cámara

Entre 1990 y 1991, Xavier Leroy diseñó una nueva implementación de Caml basada en un intérprete de código de bytes 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. [9] Esta nueva implementación, conocida como Caml Light , reemplazó la antigua implementación Caml y se ejecutó en pequeñas máquinas de escritorio. [10] En los años siguientes, aparecieron bibliotecas como las herramientas de manipulación de sintaxis de Michel Mauny que ayudaron a promover el uso de Caml en equipos educativos y de investigación. [9]

Luz especial Caml

En 1995, Xavier Leroy lanzó Caml Special Light, que era una versión mejorada de Caml. [10] Se agregó un compilador de código nativo optimizado al compilador de código de bytes, lo que aumentó considerablemente el rendimiento a niveles comparables con los lenguajes convencionales como C++ . [9] [10] Además, Leroy diseñó un sistema de módulos de alto nivel inspirado en el sistema de módulos de Standard ML que proporcionó potentes funciones de abstracción y parametrización y facilitó la construcción de programas a mayor escala. [9]

cámara objetiva

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 llevó al surgimiento del lenguaje Objective Caml, lanzado por primera vez en 1996 y posteriormente renombrado a OCaml en 2011. Este sistema de objetos admitía notablemente muchos modismos predominantes orientados a objetos de una manera estáticamente segura, mientras que esos mismos modismos causaban falta de solidez o eran necesarios. Comprobaciones de 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. [9] [10]

Desarrollo en curso

Se han agregado mejoras de lenguaje de manera incremental durante las últimas dos décadas para respaldar las crecientes bases de código comerciales y académicas en OCaml. [9] 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. [9] La versión OCaml 5.0.0 en 2022 [11] es una reescritura completa del tiempo de ejecución del lenguaje, eliminando el bloqueo global de GC y agregando 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 de INRIA hasta 2005, cuando fue sucedido por el equipo Gallium. [12] Posteriormente, Gallium fue reemplazado por el equipo de Cambium en 2019. [13] [14] A partir de 2023, hay 23 desarrolladores principales de la distribución del compilador de una variedad de organizaciones [15] y 41 desarrolladores para las herramientas OCaml más amplias. y ecosistema de embalaje. [dieciséis]

Características

OCaml presenta un sistema de tipos estáticos , inferencia de tipos , polimorfismo paramétrico , recursividad de cola , coincidencia de patrones , cierres léxicos de primera clase , funtores (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étodos son compatibles, independientemente de su herencia declarada (una característica inusual en lenguajes de tipado estático).

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

La distribución 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 el soporte de generación de código nativo para las principales arquitecturas:

El compilador de código de bytes 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 de bytes y código nativo OCaml se pueden escribir en un estilo multiproceso , con cambio de contexto preventivo. Los subprocesos OCaml en el mismo dominio [18] se ejecutan únicamente compartiendo tiempo. Sin embargo, un programa OCaml puede contener varios dominios. Existen varias bibliotecas para informática distribuida, como Functory y ocamlnet/Plasma.

Entorno de desarrollo

Desde 2011, se han aportado muchas herramientas y bibliotecas nuevas al entorno de desarrollo OCaml: [19]

Ejemplos de código

Los fragmentos de código OCaml se estudian más fácilmente ingresándolos en el REPL de nivel superior . Esta es una sesión OCaml interactiva que imprime los tipos inferidos de expresiones resultantes o definidas. [20] 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 ;; - : entero = 7   

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

Hola Mundo

El siguiente programa "hola.ml":

print_endline  "¡Hola mundo!"

se puede compilar en un ejecutable de código de bytes:

$ ocamlc hola.ml -o hola

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

$ ocamlopt hola.ml -o hola

y ejecutado:

$ ./hola ¡Hola mundo! ps

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

Opción

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

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

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

dejar  extraer  o  =  hacer coincidir  o  con  |  Algunos  i  ->  string_of_int  i  |  Ninguno  ->  "" ;;
#  extraer  ( Algunos  42 );; -  :  cadena  =  "42" #  extraer  Ninguno ;; -  :  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, enteros , que se supone que es una lista de números enteros. Tenga en cuenta la palabra clave recque indica que la función es recursiva. La función itera recursivamente sobre la lista dada de números enteros 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.

let  rec  sum  enteros  =  (* La palabra clave rec significa 'recursivo'. *)  haga coincidir  números enteros  con  |  []  ->  0  (* Da 0 si los números enteros son 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 ];;  -  :  entero  =  15

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

vamos  a sumar  números enteros  =  Lista . fold_left  ( acumulador divertido  x -> acumulador + x ) 0 enteros ;;       
 #  suma  [ 1 ; 2 ; 3 ; 4 ; 5 ];;  -  :  entero  =  15

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

vamos  a sumar  números enteros  =  Lista . fold_left  (+)  0  enteros

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

let  suma  =  Lista . doblar_izquierda  (+)  0

Ordenación rápida

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

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

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

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

problema de cumpleaños

El siguiente programa calcula el número más pequeño de personas en una habitación para quienes la probabilidad de cumpleaños completamente únicos es inferior al 50% (el problema de 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  ​​tamaño_año  =  365 .let  rec  cumpleaños_paradoja  prob  personas  =  let  prob  =  ( año_tamaño  -.  flotar  personas )  /.  tamaño_año  *.  prob  en  si  prob  <  0 . 5  luego  Imprimirf . printf  "respuesta = %d \n "  ( personas + 1 )  else  problema de paradoja_cumpleaños  ( personas + 1 ) ;; cumpleaños_paradoja  1 . 0  1

Números de la iglesia

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

deja  cero  f  x  =  x deja  succ  n  f  x  =  f  ( n  f  x ) deja  uno  =  succ  cero deja  dos  =  succ  ( succ  cero ) deja  sumar  n1  n2  f  x  =  n1  f  ( n2  f  x ) deja  to_string  n  =  n  ( divertido  k  ->  "S"  ^  k )  "0" let  _  =  to_string  ( agregar  ( 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 . A medida que la función factorial crece muy rápidamente, rápidamente desborda los números de precisión de la máquina (normalmente 32 o 64 bits). Por tanto, el 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:

#  # utilizar  "topfind" ;; #  # requiere  "núm" ;; #  abrir  numero ;;

Luego, la función factorial se puede escribir usando los operadores numéricos de precisión arbitraria =/ , */ y -/  :

#  let  rec  fact  n  =  if  n  =/  Int  0  entonces  Int  1  else  n  */  fact ( n  -/  Int  1 );; hecho val  : Núm . número -> Núm . número = < diversión >      

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

#  string_of_num  ( hecho  ( Int  120 ));; -  :  cadena  = "6689502913449127057588118054090372586752746333138029810295671352301633 557244962989366874165271984981308157637893214090 55253440858940812185989 84811143896500059649605212569600000000000000000000000000000"

Triángulo (gráficos)

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

let  ()  =  ignorar  ( Glut . init  Sys . argv );  Exceso . initDisplayMode  ~ double_buffer : verdadero  () ;  ignorar  ( Glut . createWindow  ~ título : "Demostración de OpenGL" );  sea  ​​el ángulo  t  =  10 .  *.  t  *.  t  en  let  render  ()  =  GlClear . claro  [  ` color  ];  GlMat . cargar_identidad  () ;  GlMat . rotar  ~ ángulo :  ( ángulo  ( Sys . tiempo  () ))  ~ z : 1 .  () ;  GlDibujar . comienza  ` triángulos ;  Lista . iter  GlDraw . vértice2  [- 1 .,  - 1 .;  0. ,  1 .;  1. ,  - 1. ];  GlDibujar . termina  () ;  Exceso . swapBuffers  ()  en  GlMat . modo  ` vista de modelo ;  Exceso . displayFunc  ~ cb : renderizar ;  Exceso . idleFunc  ~ cb :( Algo  de exceso . postRedisplay );  Exceso . bucle principal  ()

Se requieren los enlaces de LablGL 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 al código nativo 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 -package lablgl.glut -linkpkg -o simple

y correr:

$ ./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 Fibonacci

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

let  fib  n  =  let  rec  fib_aux  m  a  b  =  emparejar  m  con  |  0  ->  un  |  _  ->  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, aplicar dos veces a una función f produce una función que aplica f dos veces a su argumento.

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

La función usa dos veces una variable de tipo 'a para indicar que se puede aplicar a cualquier función f mapeando desde un tipo 'a a sí mismo, en lugar de solo a funciones int->int . En particular, dos veces incluso se pueden aplicar a sí mismo.

 #  let  fourtimes  f  =  ( dos veces  dos )  f ;;  val  cuatro veces  :  ( ' a  ->  ' a )  ->  ' a  ->  ' a  =  < diversión > # let add4 = cuatro veces inc ;; val add4 : int -> int = < diversión > # add4 98 ;; - : entero = 102                      

Idiomas derivados

MetaOCaml

MetaOCaml [23] 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 aceleraciones significativas utilizando la programación de varias etapas, porque en el tiempo de ejecución hay disponible información más detallada sobre los datos a procesar que en el tiempo de compilación normal, por lo que el compilador incremental puede optimizar muchos casos de verificación de condiciones, etc.

Como ejemplo: si en tiempo de compilación se sabe que se necesita alguna función de potencia con frecuencia, pero el valor de solo se conoce en tiempo de ejecución, se puede usar 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,  entonces  sqr  (  potencia (  n / 2 ) x  ) más  .  <.~ x  *.  .~( potencia  ( n  -  1 )  x )>.

Tan pronto como nse conozca en tiempo de ejecución, se puede crear una función de energía especializada y muy rápida:

.< diversión  x  ->  .~( potencia  5  .< x >.)>.

El resultado es:

divertido  x_1  ->  ( x_1  *  let  y_3  =  let  y_2  =  ( x_1  *  1 )  en  ( y_2  *  y_2 )  en  ( y_3  *  y_3 ))

La nueva función se compila automáticamente.

Otras lenguas derivadas

Software escrito en OCaml

Usuarios

Al menos varias docenas de empresas utilizan OCaml hasta cierto punto. [30] Ejemplos notables incluyen:

Referencias

  1. ^ "Módulos" . Consultado el 22 de febrero de 2020 .
  2. ^ Xavier Leroy (1996). "Objetivo Caml 1.00". lista de correo caml-list.
  3. ^ "Notas de la versión de OCaml 5.1.1" . Consultado el 27 de diciembre de 2023 .
  4. ^ "Influencias: la referencia a Rust". La referencia del óxido . Consultado el 31 de diciembre de 2023 .
  5. ^ "Una historia de OCaml" . Consultado el 24 de diciembre de 2016 .
  6. ^ Noticias semanales de Linux.
  7. ^ "AJ Milner - Premio AM Turing". amturing.acm.org . Consultado el 6 de octubre de 2022 .
  8. ^ ab al., Michael Clarkson et. "1.2. OCaml · Programación funcional en OCaml". cursos.cs.cornell.edu . Consultado el 6 de octubre de 2022 .
  9. ^ abcdefghi "Prólogo - OCaml del mundo real". dev.realworldocaml.org . Consultado el 6 de octubre de 2022 .
  10. ^ abcdefg "Una historia de OCaml - OCaml". v2.ocaml.org . Consultado el 7 de octubre de 2022 .
  11. ^ "Lanzamiento del paquete OCaml 5.0.0 OCaml". OCaml . Consultado el 16 de diciembre de 2022 .
  12. ^ "Proyecto Cristal". cristal.inria.fr . Consultado el 7 de octubre de 2022 .
  13. ^ "Equipo de galio - Inicio". galio.inria.fr . Consultado el 7 de octubre de 2022 .
  14. ^ "Inicio". cambium.inria.fr . Consultado el 7 de octubre de 2022 .
  15. ^ "Gobierno y membresía del compilador OCaml". 2023.
  16. ^ "Gobernanza y proyectos de OCaml". 2023.
  17. ^ "ocaml/asmcomp en el tronco · ocaml/ocaml · GitHub". GitHub . Consultado el 2 de mayo de 2015 .
  18. ^ Un dominio es una unidad de paralelismo en OCaml, un dominio generalmente corresponde a un núcleo de CPU
  19. ^ Los mantenedores de OCaml.org (2023). "La plataforma OCaml".
  20. ^ "OCaml: el sistema de nivel superior o REPL (ocaml)". ocaml.org . Consultado el 17 de mayo de 2021 .
  21. ^ "OCaml - Compilación por lotes (Ocamlc)".
  22. ^ "3.7. Opciones - Programación OCaml: correcta + eficiente + hermosa". cs3110.github.io . Consultado el 7 de octubre de 2022 .
  23. ^ oleg-at-okmij.org. "BER MetaOCaml". okmij.org .
  24. ^ "GitHub - johnwhitington/camlpdf". GitHub . 14 de diciembre de 2022.
  25. ^ "Messenger.com ahora 50% convertido a Reason · Reason". razónml.github.io . Consultado el 27 de febrero de 2018 .
  26. ^ "Flow: un verificador de tipos estáticos para JavaScript". Fluir .
  27. ^ "Inferir analizador estático". Inferir .
  28. ^ "GitHub - facebook/pyre-check: verificación de tipos eficaz para Python". 9 de febrero de 2019 - vía GitHub.
  29. ^ "WebAssembly/spec: especificación de WebAssembly, intérprete de referencia y conjunto de pruebas". Consorcio Mundial de la red . 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: ¡Ha llegado la versión 1.0! | Tecnología en Bloomberg". Tecnología en Bloomberg . 8 de septiembre de 2016 . Consultado el 21 de mayo de 2017 .
  32. ^ Scott, David; Agudo, Richard; Gazagnaire, Thomas; Madhavapeddy, Anil (2010). Uso de programación funcional dentro de un grupo de productos industriales: perspectivas y percepciones. Congreso Internacional sobre Programación Funcional . Asociación para Maquinaria de Computación . doi :10.1145/1863543.1863557.
  33. ^ "Flujo en GitHub". GitHub . 2023.
  34. ^ Yaron Minsky (1 de noviembre de 2011). "OCaml para las masas" . Consultado el 2 de mayo de 2015 .
  35. ^ Yaron Minsky (2016). "Keynote - Observaciones de un programador funcional". Usos comerciales de ACM de la programación funcional.
  36. ^ Yaron Minsky (2023). "Señales e hilos" (Podcast). Calle Jane 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