- OxCaml es un conjunto de extensiones que agrega capacidades orientadas al rendimiento a OCaml
- Funciona como el compilador de producción de Jane Street y como un laboratorio de funciones futuras para OCaml
- Busca ampliar el control del rendimiento priorizando la seguridad, la comodidad y la previsibilidad
- Ofrece funciones en varias áreas, como fearless concurrency, control de layouts y control de asignación
- Se ofrece como software de código abierto para que usuarios experimentales e investigadores puedan probarlo libremente y aportar opiniones
Introducción a OxCaml
Qué es OxCaml
- OxCaml es un conjunto de extensiones en rápida evolución para el lenguaje de programación OCaml
- Es el compilador de uso práctico de Jane Street y una plataforma experimental para reforzar la programación centrada en el rendimiento en OCaml
- El objetivo es contribuir estas extensiones a OCaml oficial a largo plazo
Principales objetivos de diseño de OxCaml
- Su propósito es ofrecer un entorno en el que se puedan controlar de forma segura, cómoda y predecible los factores que determinan el rendimiento del comportamiento de un programa
- Ese control se ofrece de forma opcional, solo cuando realmente hace falta
- Todo se implementa dentro del entorno de OCaml
Enfoque de diseño concreto
-
Seguridad: refuerza la seguridad del lenguaje para garantizar la productividad del programador y la corrección del código. Los lenguajes ampliamente inseguros son difíciles de usar
-
Comodidad: brinda control sin aumentar la complejidad de la programación y conserva las ventajas de la inferencia de tipos
-
Previsibilidad: expone de forma explícita a nivel del sistema de tipos las características clave de rendimiento, facilitando razonar sobre el desempeño del código
-
Estas extensiones siguen un enfoque pay-as-you-go, es decir, se aplican solo donde se necesitan. Si no se usan, se puede mantener la simplicidad y los patrones del OCaml existente
-
OxCaml es compatible con todos los programas de OCaml y, en lo interno, apunta a una evolución de OCaml. Conserva la seguridad, facilidad de uso y productividad del OCaml actual
Funciones de extensión de OxCaml
Fearless concurrency
- Para resolver lo difícil que es hacer programación concurrente correctamente, OxCaml extiende el sistema de tipos para bloquear estáticamente las carreras de datos
Layouts
- Permite que el programador especifique explícitamente el layout de los datos en memoria
- También ofrece acceso nativo a extensiones de procesadores SIMD del hardware moderno
Control de asignación
- Proporciona herramientas para controlar finamente la asignación de memoria, reduciendo la carga del recolector de basura (GC) y mejorando la eficiencia de caché y el determinismo del programa
Mejoras de calidad de vida
-
Además de la programación de sistemas, ofrece funciones que han sido útiles en tareas individuales
- Polymorphic parameters
- Include functor
- Labeled tuples
- Immutable arrays
Uso y adopción de OxCaml
-
OxCaml es de código abierto, por lo que investigadores, usuarios experimentales y desarrolladores pueden contribuir mediante pruebas y retroalimentación
-
Sin embargo, las extensiones de OxCaml no garantizan estabilidad ni compatibilidad hacia atrás (aunque sí se garantiza compatibilidad hacia atrás con los programas existentes de OCaml)
-
Se ofrecen versiones de las herramientas estándar de OCaml adaptadas para OxCaml
- Gestión de paquetes: compatible con dune y opam
- Integración con editores: soporte para LSP-server
- Formateo de código fuente y generación de documentación incluidos
-
Varias bibliotecas y herramientas publicadas por Jane Street se ofrecen en dos formas
- Para OCaml upstream: versiones sin las extensiones de OxCaml
- Exclusivas de OxCaml: versiones que aprovechan las extensiones
-
Algunas extensiones no se pueden eliminar, por lo que esas bibliotecas solo pueden usarse en OxCaml. Si las extensiones necesarias se integran en el OCaml oficial, también se publicará una versión compatible con OCaml
1 comentarios
Comentarios en Hacker News
Quiero mencionar que, en relación con este proyecto creado por el equipo de Jane Street, hubo una discusión interesante en un episodio de podcast donde participaron sobre las consideraciones de rendimiento al trabajar con OCaml
Sigue siendo un tema la preocupación por aplicar lenguajes con GC a entornos de latencia ultrabaja
Por ejemplo, si una pausa del GC ocurre en medio de una operación de trading de alta frecuencia, podría ser un problema grave
Comparto el enlace al podcast
También comparto que una vez le pregunté directamente a Ron Minsky en Twitter por qué no usan Rust para aplicaciones de baja latencia
En su respuesta, reconoció que Rust es excelente, pero puso el foco en el valor de mantener todo el código en un solo lenguaje
Es muy útil poder compartir tipos, herramientas, bibliotecas e idioms, además de facilitar moverse entre proyectos
También mencionó que OCaml está evolucionando para integrar internamente muchas de las principales ventajas de Rust y permitir una adopción gradual
Entre las desventajas de Rust mencionó tiempos de compilación largos, un sistema de tipos complejo y molestias con el manejo de async/await
Sobre todo, enfatizó que quieren una sola herramienta de lenguaje adecuada para un entorno de trabajo amplio
Enlace al tuit
Se enfatiza que el problema central no es el hecho de que sea un lenguaje con GC, sino más bien la perspectiva de tratar a todos los lenguajes con GC como si fueran iguales
El verdadero problema importante aparece cuando un lenguaje con GC no permite manipulación explícita de stack y tipos por valor
Si se busca la productividad de un lenguaje con GC junto con opciones finas para programación a nivel de sistemas, se mencionan alternativas como Cedar, la familia Oberon, Modula-3, D, Nim, Eiffel, C#, F#, Swift y Go
Como comentario general sobre runtimes que usan GC, se puede recurrir a algoritmos de recolección paralela del JVM para minimizar las pausas del GC
Sin embargo, este método no ofrece garantías uniformes, así que además puede requerirse sobreaprovisionar la RAM del sistema
Más aún, también existe la opción de sobreaprovisionar deliberadamente los servidores para permitir que algunos salgan temporalmente del pool y hagan "GC offline"
Este enfoque requiere colaboración entre el router de solicitudes y los servidores, así que solo resulta realmente útil si hay suficiente presupuesto para escalar infraestructura
Explicación del GC paralelo del JVM
Se comparte la experiencia de que varios sistemas han sufrido por problemas de compactación del GC
En sistemas de trading, normalmente se aplica la política de minimizar las asignaciones después del arranque
En JS existe una biblioteca llamada "Zero" que ofrece utilidades sin asignación
No revisé el enlace, pero opino que en un entorno como trading, donde hay periodos de apertura y cierre del mercado, también podría ser posible desactivar el GC durante la sesión y reiniciar después del cierre
Quiero destacar que la primera funcionalidad de este fork que llegó upstream fue
labeled tupleEstá previsto que se soporte en OCaml 5.4
Enlace al PR upstream
Enlace a la discusión relacionada
Aunque esta funcionalidad pueda parecer algo menor, personalmente hay bastante expectativa
También quiero agregar como referencia el paper y el video presentados por el autor de esta funcionalidad en ML2024
Video en YouTube
PDF del paper
Como ejemplo de
labeled tuple, puede ayudar a evitar errores en el orden de un par, aunque personalmente me gustan más los registros anónimos de F#Por ejemplo, con
{| product = 6; sum = 5 |}el orden de los campos no tiene importancia, así que no hay posibilidad de confundirseEn este fork también se integró
immutable arrayen 5.4, aunque la sintaxis cambia un pocoQuiero enfatizar que los
structyenumanónimos con etiquetas están entre las funciones que más me gustaría ver en un lenguaje de programaciónPor ejemplo, en Rust se pueden definir tanto
structcon etiquetas como sin etiquetas, pero resulta frustrante no poder usar unstructanónimo con etiquetas como tipo de retorno de una funciónNo sabía que este fork soportaba SIMD
Si además de tipos sin boxing, asignación explícita en stack y soporte para Windows, esto sigue avanzando, creo que OxCaml podría volverse perfectamente utilizable en entornos de consumo como game dev en lugar de F#
El soporte para Windows no está bloqueado, pero sí requiere algo de trabajo
Personalmente quería señalar que OxCaml sí agregó soporte para SIMD
Comparto un tip de configuración de variables de entorno para quienes usen un nuevo
opam switchenv OCAMLPARAM="alert=-unsafe_multidomain,_," opam install cohttp-lwt-unixSi las alertas se elevan a errores, eso puede romper innecesariamente la instalación de paquetes existentes
Se puede evitar ese problema desactivando esa alerta mediante la variable de entorno
OCAMLPARAMEstoy acostumbrado a un excelente plugin de vscode para Golang, así que me pregunto si hay planes para integrar también el entorno de OCaml con vscode
La integración con vscode hizo que la configuración fuera muy sencilla
Si OxCaml gana popularidad, naturalmente podría avanzar también su integración
Yo personalmente uso emacs, así que no puedo hablar en mucho detalle, pero parece un camino natural
Quiero mencionar una versión micro de OcaML
Enlace al proyecto mlite
Se pregunta si el motivo de hacer público este proyecto podría ser permitir que los LLM indexen la información y la usen en modelos abiertos
Los LLM ya son bastante malos incluso con OCaml normal, y como de OxCaml hay todavía menos datos, no creo en absoluto que esa sea la razón
Para ese objetivo tendría más sentido crear un MCP de documentación propia
Como señal, no tiene suficiente valor y en la práctica no significa mucho
Por ejemplo, incluso al completar código en Gleam el rendimiento de los LLM es muy bajo, y fallan aunque se les den patrones claros e instrucciones sobre errores
Por eso, la señal es demasiado débil como para pensar que el objetivo sea proveer información sobre OxCaml
Un punto curioso es que OxCaml sea una extensión de un dialecto de la familia ML que a su vez ya es un dialecto
Me da curiosidad ver cuál será el siguiente paso
Alguna vez me he preguntado quién es más problemático: la gente que sigue agregando funciones a un lenguaje existente o la que directamente crea uno nuevo
Yo pertenezco al segundo grupo, pero creo que los programadores tienen una característica genética que les impide dejar las herramientas tal como están
Como broma, sugieren si de paso podrían presentar también F#
Se confirma que el motivo de usar el nombre "oxidized" en este proyecto tiene que ver con objetivos de funcionalidad asociados a Rust, como
fearless concurrencyo evitar el GC, y no porque realmente usen RustSe comenta que el nombre puede resultar un poco confuso
De hecho, se señala la pequeña ironía de que el nombre Rust no viene del óxido, sino del hongo llamado "rust"
Se comparte que Jane Street lleva tiempo publicando una serie de blogs llamada "Oxidizing OCaml"
También se usó este término en el título del paper "Oxidizing OCaml with Modal Memory Management", aunque dentro del paper la palabra
oxidizeno parece estar definida claramente ni citadaEs un nombre algo extraño, pero da la impresión de ser bastante pegajoso
Se predice que, del lado de Rust, la integración con un GC de tracing personalizado —que puede manejar estructuras de grafo generales mientras busca el máximo rendimiento— seguirá siendo más práctica hasta que este proyecto alcance paridad funcional con Rust
De lo contrario, da la impresión de que se mantiene sobre todo porque ya existe mucho código relacionado con OxCaml