我面临着构建要集成到大型现有C代码库中的新组件的任务。该组件本质上是一种编译器,并且将足够复杂以至于我想在OCaml中编写它(出于与给定here的那些原因一致的原因)。我知道OCaml-C交互是可能的(根据manual和tutorial),但它看起来有些痛苦。
我想知道的是,这里的其他人是否尝试过大规模集成OCaml和C代码,他们发现了一些意想不到的问题,以及最后他们是否认为他们会有最好只用C编写新代码。
注意,我不试图开始讨论功能性与命令式编程的优点:让我们假设我们假设OCaml恰好是我想到的工作的正确工具,整合的潜在困难是唯一的问题。我也没有选择重写代码库的其余部分。
提供有关任务的更多细节:我需要实现的组件是某种查询优化器,它结合了我在加州大学戴维斯分校工作的一些研究思路,并将集成到PostgreSQL中,以便我们可以运行实验。 (查询优化器本质上是一个编译器。)该组件将从C代码调用,它将主要独立运行,但会对其他PostgreSQL组件进行一定数量的调用以检索系统目录信息等内容,并构建一个复杂的C数据结构(表示物理查询计划)作为输出。
对这个有点开放式的问题表示抱歉,但我希望社区能够为我节省一些麻烦:)
谢谢,
TJ
答案 0 :(得分:11)
好问题。你应该使用更好的工具来完成工作。
如果事实上你的意图是使用更好的工具(你肯定lexx和yacc将会很痛苦),那么我有一些东西要与你分享;从c调用ocaml并不痛苦,反之亦然。大多数时候我一直在写ocaml呼叫C,但我已经写了一些其他的方式。它们主要是不返回结果的调试函数。虽然,回调和第四回调实际上是关于在C侧打包和解包ocaml value
类型。你提到的那个教程涵盖了所有这些,非常好。
我反对Ron Savage评论说你必须是这门语言的专家。我记得从我工作的地方开始,在几个月内,不知道什么是“仿函数”,能够调用C,并编写数千行C用于数字配方和抽象数据类型,并且有一些打嗝(不是使用解包类型,而是使用抽象数据类型的垃圾收集),但它一点也不差。项目中的大多数内部循环都是用C语言编写的 - 具有SSE,外部库(lapack),更严格的优化循环以及一些内联手动优化组件的优势。
我认为您可能需要具备设计大型项目和划分功能和命令部分的经验。我真的会评估你要编写多少ocaml,以及你希望传递给C的值是什么 - 我说这是因为我害怕建议某人传递递归数据结构ocaml到C,实际上,它会解决许多解包元组,它们的内容,因而有很多混淆和错误的可能性。
答案 1 :(得分:2)
互操作性是静态类型语言的独立实现的致命弱点,特别是那些没有像OCaml这样的JIT编译的语言。我自己使用OCaml超过5年的经验是,唯一可靠的绑定是跨越简单的API,只需传递大型数组,例如: LAPACK。即使像FFTW那样稍微复杂的绑定也需要数年时间才能稳定下来,而像OpenGL和GLU这样的其他绑定仍然是一个未解决的问题。特别是,我发现了OCaml编译器的两位作者编写的绑定代码中的主要错误。如果他们做不到,那么我们其他人就没有希望......
然而,一切都不会丢失。解决方案只是使用更松散的绑定。不是使用低级类型不安全接口处理C级别的互操作性,而是使用XML-RPC等高级接口,通过字符串传递甚至通过套接字。这样做更容易,正如您所说,可以让您利用OCaml为此应用程序提供的巨大实际好处。
答案 2 :(得分:1)
我的经验法则是坚持使用现有代码库中使用的语言/模型/样式,以便将来的维护开发人员继承一套一致且易于理解的应用程序代码。
我能证明你所建议的东西的唯一方法就是:
如果你对C语言比OCaml更熟悉,那么在编写编译器时,你只是失去了OCaml更容易使用的任何“理论”收益 - 而且看起来你会有更多熟悉C语言的同行你比OCaml。
这是我的“脾气暴躁的老编码器”2美分(过去只花了一分钱!)。
答案 3 :(得分:1)
我写了一篇相当复杂的OCaml-C混合程序。我对发现的文档不足感到沮丧,最后我花了太多时间处理垃圾收集问题。但是,由此产生的程序运作起来很快。
我认为有一个OCaml-C集成的地方,但确保它值得麻烦。让程序通过套接字进行通信可能更简单(假设这样的IO操作不会消除您想要的性能)。用C语言写完整个东西也可能更合理。