【发布时间】:2012-03-23 17:02:28
【问题描述】:
我正在阅读OCaml lead designer's 1994 paper on modules, types, and separate compilation.(Norman Ramsey 在another question 中向我指出)。我知道这篇论文讨论了 OCaml 当前模块类型/签名系统的起源。因此,作者建议对签名中的类型声明(以允许单独编译)以及清单类型声明(为了表达性)进行不透明的解释。尝试整理我自己的一些示例来演示 OCaml 模块签名表示法试图解决的问题类型,我在两个文件中编写了以下代码:
在文件ordering.ml(或.mli——我都试过了)(文件A):
module type ORDERING = sig
type t
val isLess : t -> t -> bool
end
在文件useOrdering.ml(文件 B)中:
open Ordering
module StringOrdering : ORDERING
let main () =
Printf.printf "%b" StringOrdering.isLess "a" "b"
main ()
这个想法是期望编译器抱怨(在编译第二个文件时)模块 StringOrdering 上没有足够的类型信息来对 StringOrdering.isLess 应用程序进行类型检查(从而激发对 with type 语法的需求)。
但是,尽管文件 A 可以按预期编译,但文件 B 会导致 3.11.2 ocamlc 抱怨语法错误。我理解签名的目的是允许某人根据模块签名编写代码,而无需访问实现(模块结构)。
我承认我不确定我在this rather old paper on separate compilation 中遇到的语法:module A : B,但这让我想知道是否存在这样或类似的语法(不涉及函子)以允许某人仅基于模块类型,链接时提供的实际模块结构,类似于在 C/C++ 中使用*.h 和*.c 文件的方式。如果没有这种能力,似乎模块类型/签名基本上是用于密封/隐藏模块内部或更明确的类型检查/注释,而不是用于单独/独立编译。
实际上,看着OCaml manual section on modules and separate compilation,我与C 编译单元的类比似乎被打破了,因为OCaml 手册将OCaml 编译单元定义为A.ml 和A.mli 二重奏,而在C/C++ 中@ 987654342@ 文件被粘贴到任何导入的.c 文件的编译单元。
【问题讨论】:
-
正如托马斯的回答暂时所说,默认情况下本机编译没有单独的编译。我希望有,为此我在 mantis 中输入了一个功能愿望:caml.inria.fr/mantis/view.php?id=4389。如果有人知道如何在 OCaml 中获得单独的本地编译(正如 Thomas 暂时声称的那样),我会非常有兴趣了解它。
-
@PascalCuoq:为什么说不能在Ocaml中单独编译原生代码?当然可以。
-
实际上,我只是按照 Thomas 的回答中的建议修改了这两个文件,实际上您可以分别编译字节码 (ocamlc) 或本机 (ocamlopt)。
-
@AndreasRossberg 这里没有重复我的功能愿望的余地,但是看看
ocamldep的输出,如果你不移动它们,它对应于.cmx文件之间的实际依赖关系防止编译器将内容从一个内联到另一个。请注意,愿望是在“不会修复”中解决的,而不是在“不需要更改”中解决的。另见frama-c.com/u3cat/download/CuoqICFP09.pdf 中的“单独编译”备注。这些从未受到挑战。我很高兴在 OCaml 中有单独的原生编译,但很多人认为没有。