All functions and methods, whether meant to be private or public, should be documented. A function documentation block should immediately precede the declaration of the function itself. For example:

/**
 * Verifies the syntax of the given e-mail address.
 *
 * Empty e-mail addresses are allowed. See RFC 2822 for details.
 *
 * @param $mail
 *   A string containing an email address.
 *
 * @return
 *   TRUE if the address is in a valid format, and FALSE if it isn't.
 */
function valid_email_address($mail) {

The first line of the block should contain a brief description of what the function does, limited to 80 characters, and beginning with a verb in the form "Does such and such" (third person, as in "This function does such and such", rather than second person imperative "Do such and such"). A longer description with usage notes should follow after a blank line, if more explanation is needed.

After the long description, each parameter should be listed with a @param directive, with a description indented by two extra spaces on the following line or lines. If there are no parameters, omit the @param section entirely. Do not include any blank lines in the @param section.

After all the parameters, a @return directive should be used to document the return value if there is one. There should be a blank line between the @param section and @return directive. If there is no return value, omit the @return directive entirely.

Functions that are easily described in one line may use the function summary only, for example:

/**
 * Converts an associative array to an anonymous object.
 */
function mymodule_array2object($array) {

If the abbreviated syntax is used, the parameters and return value must be described within the one-line summary.

If the data type of a parameter or return value is not obvious or expected to be of a special class or interface, it is recommended to specify the data type in the @param or @return directive:

/**
 * Execute an arbitrary query string against the active database.
 *
 * Do not use this function for INSERT, UPDATE, or DELETE queries. Those should
 * be handled via the appropriate query builder factory. Use this function for
 * SELECT queries that do not require a query builder.
 *
 * @param object $query
 *   The prepared statement query to run. Although it will accept both named and
 *   unnamed placeholders, named placeholders are strongly preferred as they are
 *   more self-documenting.
 * @param array $args
 *   An array of values to substitute into the query. If the query uses named
 *   placeholders, this is an associative array in any order. If the query uses
 *   unnamed placeholders (?), this is an indexed array and the order must match
 *   the order of placeholders in the query string.
 * @param array $options
 *   An array of options to control how the query operates.
 *
 * @return DatabaseStatementInterface
 *   A prepared statement object, already executed.
 *
 * @see DatabaseConnection::defaultOptions()
 */
function db_query($query, array $args = array(), array $options = array()) {
  // ...
}

Primitive data types, such as int or string, are not specified. It is recommended to specify classes and interfaces. If the parameter or return value is an array, or (anonymous/generic) object, you can specify the type if it would add clarity to the documentation. If for any reason, a primitive data type needs to be specified, use the lower-case data type name, e.g. "array".