2010-08-11 34 views
13

Tengo la tarea de construir un nuevo componente para integrarlo en una gran base de código C existente. El componente es esencialmente un tipo de compilador, y será lo suficientemente complicado como para escribirlo en OCaml (por razones similares a las dadas en here). Sé que la interacción OCaml-C es posible (según el manual y este tutorial), pero parece algo doloroso.Mezclar OCaml y C: ¿vale la pena?

Lo que me gustaría saber es si otros aquí han intentado la integración a gran escala de OCaml y el código C, cuáles fueron algunos de los errores inesperados que encontraron, y si al final del día llegaron a la conclusión de que lo harían han sido mejor simplemente escribir el nuevo código en C.

Nota, soy no tratando de iniciar un debate sobre los méritos de funcional en comparación con la programación imperativa: digamos que suponemos que OCaml pasa a ser la derecha herramienta para el trabajo que tengo en mente, y la dificultad potencial en la integración es el único problema. Tampoco tengo la opción de volver a escribir el resto de la base de código.

Para dar un poco más de detalle sobre la tarea: el componente que necesito implementar es un cierto tipo de optimizador de consultas que incorpora algunas ideas de investigación que mi grupo de UC Davis está trabajando y se integrará en PostgreSQL para que podamos puede ejecutar experimentos. (Un optimizador de consultas es, esencialmente, un compilador.) El componente se invocaría desde el código C, funcionaría en su mayoría de forma independiente pero haría una cierta cantidad de llamadas a otros componentes de PostgreSQL para recuperar cosas como la información del catálogo del sistema y construiría un complejo Estructura de datos C (que representa un plan de consulta física) como salida.

Disculpas por la pregunta un poco abierta, pero espero que la comunidad podría ser capaz de ahorrar un poco de problemas :)

Gracias,

TJ

+0

Por curiosidad, ¿qué tipo de ocaml está esperando que C tenga que desempaquetar? – nlucaroni

Respuesta

10

Gran pregunta. Deberías usar la mejor herramienta para el trabajo.

Si de hecho sus intenciones son utilizar la mejor herramienta para el trabajo (y está seguro de que lexx y yacc serán un dolor) entonces tengo algo que compartir con usted; no es doloroso llamar a ocaml desde c, y viceversa. La mayor parte del tiempo he estado escribiendo ocaml llamando a C, pero he escrito algunas a la inversa. En su mayoría han sido funciones de depuración que no devuelven un resultado.Aunque, los llamamientos de vuelta y cuarto se refieren realmente a empacar y desempacar el tipo ocaml value en el lado C. Ese tutorial que mencionas cubre todo eso, y muy bien.

Me opongo a las observaciones de Ron Savage de que tienes que ser un experto en el idioma. Recuerdo haber comenzado donde trabajo, y en pocos meses, sin saber qué era un "functor", poder llamar a C y escribir mil líneas de C para recetas numéricas y tipos de datos abstractos, y hubo algunos contratiempos (no con los tipos de desempaquetado, pero con la recolección de basura de un tipo de datos abstracto), pero no estuvo nada mal. La mayoría de los bucles internos del proyecto están escritos en C: aprovechando la SSE, las bibliotecas externas (lapack), los bucles optimizados más ajustados y algunos ensamblajes optimizados a mano alineados.

Creo que puede necesitar experiencia en el diseño de un proyecto grande y demarcación de secciones funcionales e imperativas. Realmente evaluaría la cantidad de mensajes que va a escribir, y qué tipo de valores quiere transmitir a C - Estoy diciendo esto porque me da miedo recomendar a alguien que pase una estructura de datos recursiva de ocaml a C, en realidad, sería un montón de desempaquetar tuplas, su contenido, y por lo tanto una gran cantidad de confusión y errores.

+2

Muy buena respuesta. Debo señalar que esto depende en gran medida de la cantidad de trabajo OCaml que se debe hacer en comparación con el dolor de integración C (tamaño API). Se aplica para integrar cualquier idioma nuevo a cualquier proyecto existente. –

+0

No solo es una buena respuesta, incluso es la que quería escuchar :) – tjgreen

1

Mi regla de oro es seguir con el lenguaje/modelo/estilo utilizado en la base de código existente, de modo que los futuros desarrolladores de mantenimiento hereden un conjunto consistente y comprensible de código de aplicación.

La única manera de que pudiera justificar algo así como lo que está sugiriendo que sería si:

  1. usted es un experto en OCaml Y un principiante en C (por lo que va a ser tan productivo 20x)
  2. Lo ha integrado con éxito con una biblioteca C antes (al parecer no)

Si está más familiarizado con C que con OCaml, acaba de perder cualquier ganancia "teórica" ​​de OCaml que es más fácil de usar al escribir un compilador - además, parece que tendrá más pares f amiliar con C a tu alrededor que OCaml.

Ese es mi codificador antiguo "gruñón" 2 centavos (¡que solía costar solo un centavo!).

+6

No entiendo por qué usted asume que uno debe ser un experto en OCaml y un novato en C para poder ser más productivo usando OCaml en un área que es precisamente su punto fuerte. Si hubiera un componente web, ¿escribirías todo eso en C en lugar de, digamos, Python + HTML + Javascript? – Chuck

+4

Pregunta: ¿La respuesta de Ron Savage en realidad se basa en algún conocimiento/específico sobre OCaml o incluso C? –

+1

@Chuck - Porque completar la función en 1 mes frente a 5 meses puede hacer que valga la pena la complejidad adicional, los dolores de cabeza de mantenimiento y el riesgo de introducir un lenguaje completamente nuevo en un proyecto existente y en un equipo de desarrolladores de C. 1 mes vs 2 meses? No vale la pena. –

1

Yo escribí un programa híbrido OCaml-C razonablemente complejo. Estaba frustrado por lo que encontré como documentación inadecuada, y terminé pasando demasiado tiempo lidiando con problemas de recolección de basura. Sin embargo, el programa resultante funcionó y fue rápido.

Creo que hay un lugar para la integración OCaml-C, pero asegúrese de que vale la pena la molestia. Puede ser más simple hacer que los programas se comuniquen a través de un socket (suponiendo que tales operaciones de IO no eliminen el rendimiento que desea). También podría ser más sensato escribir todo en C.

1

La interoperabilidad es el talón de Aquiles de implementaciones independientes de lenguajes tipados estáticamente, particularmente aquellos sin compilación JIT como OCaml. Mi propia experiencia al haber usado OCaml durante más de 5 años es que los únicos enlaces confiables se encuentran en API simples que hacen poco más que pasar grandes arreglos, p. LAPACK. Incluso los enlaces ligeramente más complicados como los de FFTW tardaron años en estabilizarse y otros, como OpenGL y GLU, siguen siendo un problema sin resolver. En particular, encontré errores importantes en el código de enlace escrito por dos de los autores del compilador OCaml. Si no pueden hacerlo bien, entonces hay pocas esperanzas para el resto de nosotros ...

Sin embargo, no todo está perdido. La solución es simplemente usar enlaces más sueltos. En lugar de manejar la interoperabilidad en el nivel C con una interfaz de tipo no seguro de bajo nivel, use una interfaz de alto nivel como XML-RPC con paso de cadena o incluso sobre sockets. Es mucho más fácil hacerlo bien y, como dices, te permitirá aprovechar los enormes beneficios prácticos que ofrece OCaml para esta aplicación.

+1

Usar IPC en lugar de escribir enlaces es una idea que a menudo se pasa por alto. ¿Por qué siempre buscan soluciones complicadas? –