I am wondering if there exists already some naming conventions for Ocaml, especially for names of constructors, names of variables, names of functions, and names for labels of record.
For instance, if I want to define a type condition, do you suggest to annote its constructors explicitly (for example Condition_None) so as to know directly it is a constructor of condition?
Also how would you name a variable of this type? c or a_condition? I always hesitate to use a, an or the.
To declare a function, is it necessary to give it a name which allows to infer the types of arguments from its name, for example remove_condition_from_list: condition -> condition list -> condition list?
In addition, I use record a lot in my programs. How do you name a record so that it looks different from a normal variable?
There are really thousands of ways to name something, I would like to find a conventional one with a good taste, stick to it, so that I do not need to think before naming. This is an open discussion, any suggestion will be welcome. Thank you!
You may be interested in the Caml programming guidelines. They cover variable naming, but do not answer your precise questions.
Regarding constructor namespacing : in theory, you should be able to use modules as namespaces rather than adding prefixes to your constructor names. You could have, say, a
Constructormodule and useConstructor.Noneto avoid confusion with the standardNoneconstructor of theoptiontype. You could then useopenor the local open syntax of ocaml 3.12, or use module aliasingmodule C = ConstructorthenC.Nonewhen useful, to avoid long names.In practice, people still tend to use a short prefix, such as the first letter of the type name capitalized,
CNone, to avoid any confusion when you manipulate two modules with the same constructor names; this often happen, for example, when you are writing a compiler and have several passes manipulating different AST types with similar types: after-parsingLetform, after-typingLetform, etc.Regarding your second question, I would favor concision. Inference mean the type information can most of the time stay implicit, you don’t need to enforce explicit annotation in your naming conventions. It will often be obvious from the context — or unimportant — what types are manipulated, eg.
remove cond (l1 @ l2). It’s even less useful if yourremovevalue is defined inside aConditionsubmodule.Edit: record labels have the same scoping behavior than sum type constructors. If you have defined a
{x: int; y : int}record in aCoordsubmodule, you access fields withfoo.Coord.xoutside the module, or with an aliasfoo.C.x, orCoord.(foo.x)using the “local open” feature of 3.12. That’s basically the same thing as sum constructors.Before 3.12, you had to write that module on each field of a record, eg.
{Coord.x = 2; Coord.y = 3}. Since 3.12 you can just qualify the first field:{Coord.x = 2; y = 3}. This also works in pattern position.