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 pro开发者_运维百科grams. 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 Constructor
module and use Constructor.None
to avoid confusion with the standard None
constructor of the option
type. You could then use open
or the local open syntax of ocaml 3.12, or use module aliasing module C = Constructor
then C.None
when 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-parsing Let
form, after-typing Let
form, 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 your remove
value is defined inside a Condition
submodule.
Edit: record labels have the same scoping behavior than sum type constructors. If you have defined a {x: int; y : int}
record in a Coord
submodule, you access fields with foo.Coord.x
outside the module, or with an alias foo.C.x
, or Coord.(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.
If you want naming convention suggestions, look at the standard library. Beyond that you'll find many people with their own naming conventions, and it's up to you to decide who to trust (just be consistent, i.e. pick one, not many). The standard library is the only thing that's shared by all Ocaml programmers.
Often you would define a single type, or a single bunch of closely related types, in a module. So rather than having a type called condition
, you'd have a module called Condition
with a type t
. (You should give your module some other name though, because there is already a module called Condition
in the standard library!). A function to remove a condition from a list would be Condition.remove_from_list
or ConditionList.remove
. See for example the modules List
, Array
, Hashtbl,
Map.Make`, etc. in the standard library.
For an example of a module that defines many types, look at Unix
. This is a bit of a special case because the names are mostly taken from the preexisting C API. Many constructors have a short prefix, e.g. O_
for open_flag
, SEEK_
for seek_command
, etc.; this is a reasonable convention.
There's no reason to encode the type of a variable in its name. The compiler won't use the name to deduce the type. If the type of a variable isn't clear to a casual reader from the context, put a type annotation when you define it; that way the information provided to the reader is validated by the compiler.
精彩评论