-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
79 additions
and
87 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,49 +1,79 @@ | ||
|
||
The following are some policies to maintain a semi-consistent style | ||
across CMlib: | ||
|
||
* Name files using the most-significant designator first, then | ||
qualifiers. Thus dict-red-black.sml, not red-black-dict.sml. | ||
|
||
* In identifier names, use English-standard word order. Thus | ||
RedBlackDict, not DictRedBlack. | ||
|
||
(The difference between file names and identifier names is because | ||
we want sorted file names to group similar functionality, but | ||
sorting is rarely important for identifier names.) | ||
|
||
* Camel case is preferred to underscores. Thus deleteNearLeaf, not | ||
delete_near_leaf. An exception is for all-caps identifiers (mainly | ||
signatures) which obviously must use underscores. | ||
|
||
* Curried functions are generally preferred to functions taking tupled | ||
arguments. | ||
|
||
There are occasions in which exceptions are reasonable, however: | ||
|
||
- One might take arguments in a tuple in order to match the usage in | ||
a similar basis function, such as a comparison function. | ||
|
||
- Since SML does not provide a convenient syntax for anonymous | ||
curried functions, a function argument of a higher-order function | ||
might take its arguments in a tuple. (For example, the first | ||
argument to a fold-like operation.) | ||
|
||
* Please avoid inexhaustive matches. | ||
|
||
* Functor arguments using specification-list notation are preferred to | ||
signature notation. That is, we prefer: | ||
|
||
functor FooFun (structure Bar : BAR) = ... | ||
|
||
to: | ||
|
||
functor FooFun (Bar : BAR) = ... | ||
|
||
Several exceptions are grandfathered in, though. | ||
|
||
* Adding an operation to a signature is usually not considered an | ||
incompatible change for versioning purposes (even though, strictly | ||
speaking, one could write SML code that depends on its absence). | ||
However, adding an operation to a type class (e.g., ORDERED or | ||
STREAMABLE) is considered an incompatible change. | ||
|
||
Code naming conventions | ||
----------------------- | ||
|
||
* Signature names should be in all caps, with underscores separating | ||
words. | ||
|
||
* Structure and functor names should be capitalized, with capitals | ||
starting words (a.k.a. camel case). | ||
|
||
* Types and terms should begin with a lower-case letter, with capitals | ||
starting following words (a.k.a. camel case). | ||
|
||
* Constructors should be capitalized, and may (optionally) be all | ||
caps. | ||
|
||
* Type classes (signatures that indicate operations on existing types, | ||
usually to serve as a functor argument) should name the principal | ||
type field "t". | ||
|
||
* Multiple implementations of an interface should be named such as | ||
AdjectiveFoo (or AdjectiveFooFun). Thus RedBlackDict, not | ||
DictRedBlack. | ||
|
||
|
||
File conventions | ||
---------------- | ||
|
||
* File names should be in all lower case, with hyphens separating | ||
words. | ||
|
||
* Files containing only signatures should be named with a ".sig" | ||
suffix. Other files should be named with a ".sml" suffix. | ||
|
||
* Multiple implementations of an interface should be given names such | ||
as foo-adjective.sml. Thus, dict-red-black.sml, not | ||
red-black-dict.sml. (Note that this file name convention differs | ||
from the structure/functor name convention. This is to allow | ||
multiple implementions to sort together.) | ||
|
||
* Type classes should generally be placed in their own files, rather | ||
than in the same file as a functor that depends on them. | ||
|
||
|
||
Other conventions | ||
----------------- | ||
|
||
* Curried functions are generally preferred to functions taking tupled | ||
arguments. | ||
|
||
There are exceptions in which tuples are reasonable, however. For | ||
example: | ||
|
||
- One might take arguments in a tuple in order to match the usage in | ||
a similar basis function, such as a comparison function. | ||
|
||
- Since SML does not provide a convenient syntax for anonymous | ||
curried functions, a function argument of a higher-order function | ||
might take its arguments in a tuple. (For example, the first | ||
argument to a fold-like operation.) | ||
|
||
* Please avoid inexhaustive matches. | ||
|
||
* Functor arguments using specification-list notation are preferred to | ||
signature notation. That is, we prefer: | ||
|
||
functor FooFun (structure Bar : BAR) = ... | ||
|
||
to: | ||
|
||
functor FooFun (Bar : BAR) = ... | ||
|
||
Several exceptions are grandfathered in, though. | ||
|
||
* Adding an operation to a signature is usually not considered an | ||
incompatible change for versioning purposes (even though, strictly | ||
speaking, one could write SML code that depends on its absence). | ||
However, adding an operation to a type class (e.g., ORDERED or | ||
STREAMABLE) is an incompatible change. |