Ocaml命名约定

时间:2011-07-18 13:39:27

标签: naming-conventions ocaml

我想知道是否已经存在一些Ocaml的命名约定,特别是对于构造函数的名称,变量的名称,函数的名称以及记录标签的名称。

例如,如果我想定义类型condition,你建议明确地声明它的构造函数(例如Condition_None),以便直接知道它是{{1}的构造函数}?

另外,您如何命名此类型的变量? conditionc?我总是犹豫使用a_conditionaan

要声明一个函数,是否有必要给它一个名称,允许从其名称推断出参数的类型,例如the

另外,我在我的程序中使用了很多记录。如何命名记录以使其看起来与普通变量不同?

有很多方法可以命名,我希望找到一个有着良好品味的传统方法,坚持下去,这样我就无需在命名前思考。这是一个公开的讨论,任何建议都将受到欢迎。谢谢!

2 个答案:

答案 0 :(得分:5)

您可能对Caml programming guidelines感兴趣。它们涵盖变量命名,但不回答您的确切问题。

关于构造函数命名空间:理论上,您应该能够将模块用作命名空间,而不是在构造函数名称中添加前缀。例如,您可以使用Constructor模块并使用Constructor.None来避免与None类型的标准option构造函数混淆。然后,您可以使用open或ocaml 3.12的本地开放语法,或者在有用时使用模块别名module C = Constructor然后使用C.None,以避免使用长名称。

在实践中,人们仍然倾向于使用短前缀,例如类型名称大写的第一个字母CNone,以避免在操作具有相同构造函数名称的两个模块时出现任何混淆;这经常发生,例如,当您编写编译器并且有几个传递操作具有相似类型的不同AST类型时:解析后Let形式,后键入Let形式等。

关于你的第二个问题,我赞成简洁。推断意味着类型信息在大多数情况下都是隐式的,您不需要在命名约定中强制使用显式注释。从上下文中可以明显看出 - 或者说不重要 - 操纵什么类型,例如。 remove cond (l1 @ l2)。如果在remove子模块中定义了Condition值,则效果更差。

编辑:记录标签与总和类型构造函数具有相同的作用域行为。如果您在{x: int; y : int}子模块中定义了Coord条记录,则可以访问模块外部foo.Coord.x的字段,或使用别名foo.C.xCoord.(foo.x) 3.12的“本地开放”特征。这与sum构造函数基本相同。

在3.12之前,您必须在记录的每个字段上编写该模块,例如。 {Coord.x = 2; Coord.y = 3}。从3.12开始,您可以限定第一个字段:{Coord.x = 2; y = 3}。这也适用于模式位置。

答案 1 :(得分:4)

如果您想要命名约定建议,请查看标准库。除此之外,你会发现许多人都有自己的命名惯例,由你来决定信任谁(只是保持一致,即选择一个,而不是很多)。标准库是所有Ocaml程序员共享的唯一内容。

通常,您会在模块中定义单个类型或一组密切相关的类型。因此,您没有名为condition的类型,而是拥有一个名为Condition的模块,其类型为t。 (你应该给你的模块一些其他名称,因为标准库中已经有一个名为Condition的模块!)。从列表中删除条件的功能是Condition.remove_from_listConditionList.remove。例如,请参阅标准库中的模块ListArrayHashtbl, Map.Make`等。

有关定义多种类型的模块的示例,请查看Unix。这是一个特殊情况,因为这些名称大多来自预先存在的C API。许多构造函数具有短前缀,例如O_open_flagSEEK_seek_command等;这是一个合理的约定。

没有理由在名称中编码变量的类型。编译器不会使用该名称来推断类型。如果变量的类型对于来自上下文的临时读者不清楚,则在定义时添加类型注释;这样,提供给读者的信息将由编译器验证。