Nuevo backend de C++ para el compilador de OCaml
(github.com/ocaml)- Se propuso un nuevo backend con soporte para generación de código C++ para el compilador de OCaml, con el fin de complementar las limitaciones del backend existente basado en C
- El código transformado se escribe en estilo funcional puro, sin estado mutable ni uso de la biblioteca estándar, reimplementando parte del módulo
List - La ejecución requiere un compilador de C++ (
g++) y admite opciones para quitar el límite de profundidad de plantillas o pasar argumentos - El rendimiento varía según el compilador, y al aplicar un algoritmo de criba mejorado basado en cola de prioridad aumentan la velocidad y la eficiencia de memoria
- La comunidad lo evalúa como un experimento de combinación entre lenguajes funcionales y metaprogramación con plantillas, y también se menciona la posibilidad de extenderlo a Rust
Propuesta para agregar un backend de C++
- Se propuso un parche para agregar un backend de C++ al compilador de OCaml (
ocamlc)- Es una versión mejorada del backend en C no incremental que ya se usa en el runtime y el FFI
- Con el comando
ocamlc -incr-c primes.mlse puede transformar código OCaml a C++
- El código C++ transformado se escribe en estilo funcional puro y no admite estado mutable
- Por esto no es posible usar la biblioteca estándar, y en el ejemplo se reimplementa de forma puramente funcional parte del módulo
List - La salida se representa como una estructura anidada con forma de
Cons<hd, tl>, usando una estructura separada para evitar conflictos con el operador::de C++
- Por esto no es posible usar la biblioteca estándar, y en el ejemplo se reimplementa de forma puramente funcional parte del módulo
- La ejecución requiere un compilador de C++ (
g++) y permite pasar argumentos con la opción-Dlimit=100- El resultado de la ejecución se muestra con formato de mensaje de error del compilador
- En cálculos grandes, se puede quitar el límite de profundidad de plantillas con la opción
-ftemplate-depth=999999
- El rendimiento varía según el compilador
g++tarda unos 30 segundos para calcular números primos hasta 10000, usando 11 GiB de memoriaclang++muestra una advertencia en menos de 1 segundo y luego falla con un error de segmentación- Al aplicar el algoritmo de criba de O’Neill basado en cola de prioridad, mejora a 8 segundos y 3.1 GiB
- Como dirección futura de expansión, se menciona soporte para Rust
- Se comenta que, si Rust completa
impl specializationparcial, sería posible ejecutar programas de OCaml
- Se comenta que, si Rust completa
Reacción y discusión en la comunidad
-
Pruebas de la funcionalidad y comentarios
redianthuspreguntó si hay soporte para tipos de datos recursivos no uniformesstedolancorrigió un error causado por la falta de implementación de%predinty confirmó que ese tipo funciona correctamente
-
Humor y reacciones
avsmdejó la broma: “Necesitábamos C-- y salió C++, así que mejor transemos con C#”stedolanrespondió: “El próximo año intentaré con el número complejo ℂ”- Hubo muchas reacciones con emojis como 😂, ❤️ y 🚀, lo que mostró una recepción positiva en la comunidad
-
Propuestas técnicas
AdelKSpropuso una alternativa usando evaluación conconstexpren lugar de plantillas- Compartió un ejemplo de código que calcula números primos en tiempo de compilación y los incluye directamente en el binario
LoganDarkrespondió en tono humorístico: “Eso sería por pura diversión”, explicando así por qué se usan plantillas
-
Discusión adicional
redianthuscomentó: “Ahora C++ se ha convertido en un verdadero lenguaje funcional”- Destacó que las estructuras de datos funcionales puras de OCaml pueden implementarse en C++
dzmitry-lahodamencionó que ya existe un proyecto capaz de ejecutar OCaml en Rust (contextgeneric/cgp)
Rendimiento y ejemplos de ejecución
- Ejemplo básico: programa para calcular números primos
ocamlc -incr-c primes.ml→ generaprimes.cpp- Al ejecutar
g++ -Dlimit=100 primes.cppse imprime la lista de números primos
-
Configuración de alto rendimiento
g++ -ftemplate-depth=999999 -Dlimit=10000 primes.cpp- Unos 30 segundos, 11 GiB de memoria usados
-
Al aplicar el algoritmo mejorado
- 8 segundos, 3.1 GiB, con mejor rendimiento
Conclusión
- Este PR es un experimento de un nuevo backend que transforma OCaml a C++ y muestra la posibilidad de combinar lenguajes funcionales con metaprogramación mediante plantillas
- La comunidad lo recibió como un caso que mezcla humor técnico y experimentación creativa, generando una discusión activa
- También se plantea la posibilidad de extenderlo a otros lenguajes como Rust
1 comentarios
Comentarios en Hacker News
Esto es realmente excelente. Quiero dar un consejo cuando se escribe código C++ de larga ejecución
Curiosamente, los intérpretes de C++ no tienen tail call optimization en absoluto
Por eso, la mayor parte del código C++ idiomático implementa directamente funciones como
reverse,map,rangeyfilterpara evitar que explote la pilaSi se implementa de esta manera, será mucho más fácil para quien tenga que mantenerlo. Es mejor usar un enfoque portable en lugar de depender de flags de línea de comandos
Me dio risa leer la frase: “si usas estas estructuras de datos avanzadas, g++ calcula los números primos menores o iguales a 10000 en solo 8 segundos y usando apenas 3.1GiB de memoria”
Por fin voy a poder hacer cálculo de números primos en mi laptop
Me identifiqué totalmente con la parte que dice: “este código se traduce a un C++ idiomático y fácil de leer”
Como alguien a quien le gusta C++, de verdad creo que este es código C++ agradable de leer
typedef I<((I<((n::val (p::val))>::val) != (I<0>::val))> res;son realmente trucos de plantillas a nivel magiaEs la primera vez que veo una expresión condicional dentro de una definición de tipo en C++
Después vi que esto no era código real, sino parte de la lógica de evaluación de plantillas
Es decir, en cierto modo delegaron parte de la lógica del compilador de un lenguaje de alto nivel al motor de plantillas
Este enfoque podría incluso ser más eficiente que dedicar más tiempo al parser
Así que ahora me dan ganas de probar C++ como target de lowering para el framework de compiladores elevate que estoy desarrollando
Cuando vi la frase “C++ is a purely functional language”, al principio levanté la ceja pensando que era un typo
Pero cuando entendí que no lo era, me pareció todavía más interesante. El resto del contenido también estuvo excelente
Este artículo me alegró el día. Gracias
Stephen Dolan no decepciona, como siempre. Cada vez sorprende
Al leer la parte que dice “C++ es un lenguaje puramente funcional y no admite estado mutable. Para ejecutar un programa en C++ hace falta un intérprete de C++”
por un momento pensé que era una broma del Día de los Inocentes. Aunque abril ya pasó