読者です 読者をやめる 読者になる 読者になる

一歩前進

プログラミングに関する雑多なメモ

OCaml モジュールとシグネチャの命名規則

モジュール名

OCamlのモジュール名は大文字から始まる必要があり、単語の区切り方は以下の2つのケースが多いようです。

  • 先頭大文字のスネークケース (例: Type_utils)
  • アッパーキャメルケース (例: TypeUtils)

前者はJane Street CoreやOcsigen等で見受けられます。後者はBatteriesやExtLib等で見受けられるスタイルです。

どちらを使うかは好みの問題なのでしょうが、特に理由がなければ

  • 公式のコーディング規約で推奨されている(ようだ)
  • Jane Street CoreやOcsigenを使った時にモジュール名の語感が合う

ということで、先頭大文字のスネークケースのスタイルを扱うのが良さそうです。

module Type_utils =
  struct
    ...
  end

シグネチャの名前

モジュールの型のようなものであるシグネチャについては、全て大文字で記述するのが慣習のようです。

module type TYPE_UTILS =
  sig
   ...
  end

ウェルズリー大学のTheory of Programming Languagesコースの資料では、 http://cs.wellesley.edu/~cs251/handouts/modules.pdf

Many OCaml programmers name signatures with all caps, but this is only a convention.

と述べられています。

コーディング規約

いくつかのコーディング規約から命名規則についてみていきます。

(1) 公式のコーディング規約

公式のコーディング規約については「アンダースコアで単語を区切る」とあります。

Caml programming guidelines

How to choose identifiers (識別子の決め方)というセクションの Separate words by underscores: (int_of_string, not intOfString) という項目です。

この「識別子(Identifiers)」が、小文字から始まる変数名や関数名のみを指しているのか、型構築子やモジュール名を含んでいるのかが気になるところです。

マニュアルをみてみると、識別子は大文字か小文字あるいはアンダースコアから始まる、と定義されています。

Lexical conventions

ということは単に「識別子」といった場合、モジュール名も該当すると考えられます。モジュールや構築子の識別子はアンダースコアで区切る、というのが推奨されているようです。(ただし、キャメルケースを使っている既存ライブラリと連携する場合は、その限りではないと書かれています。)

(2) OCaml Best Practices for Developers

Xen API (XAPI) のOCamlライブラリのプロジェクトで使われているコーディング規約です。

OCaml Best Practices for Developers - Xen

以下のように、単語の区切りはアンダースコアであり、略語が続く場合は大文字可としています。

module Parser = struct...end
module Locking_strategy = struct...end
module XML_UTF8 = struct...end

なお、シグネチャについては大文字でアンダースコア区切りとしていますが、読みやすさを妨げない事が前提となっています。

module type CAR_FACTORY = sig...end
module Fast_car_factory : CAR_FACTORY = struct...end

(3) CS3110 OCaml Style Guide

コーネル大学のData Structures and Functional Programmingのコースで配布しているコーディング規約では、構築子やモジュールの命名規則はアッパーキャメルケースとしてます。また、ファンクタについてはFnを付けています。

CS3110 OCaml Style Guide

上記資料より抜粋:

Token OCaml Naming Convention Example
Variables Symbolic or initial lower case. Use snake_case instead of studlyCaps. getItem, getItem
Constructors Initial upper case. Use StudlyCaps for multiword names. Historic exceptions are nil, true, and false. Rarely are symbolic names like :: used. Node, EmptyQueue
Types All lower case. Use underscores for multiword names. priority_queue
Signatures All upper case. Use underscores for multiword names. PRIORITY_QUEUE
Structures Initial upper case. Use embedded caps for multiword names. PriorityQueue
Functors Same as for structures, except Fn completes the name. PriorityQueueFn

先頭大文字のスネークケースというのは、他の言語ではあまり見られない慣習です。混乱を招くことが考えられる場合には、上記のような規約を導入し、特に理由が無い場合は公式のスタイルに準拠するのが良さそうです。