.ds CX $Header: names,v 5.2 86/05/02 19:04:20 peter Exp $
.ds CC (C) Copyright 1984 by Third Eye Software, Inc. - All Rights Resereved
.nr N 4
.nr O 1i
.nr S 12
.so /usr/lib/tmac/tmac.m
.TL
Type, Variable and Procedure Naming Conventions
.AU "Peter W. Rowell" PWR
.MT 4
.P
The names used throughout Third Eye Software's various products
adhere to a fairly rigid system.
This system is based on one originally developed by Charles Simonyi.
There are several aims to this system, the most important of which are:
.BL 5
.LI
Visual type checking.
It is \fIimmediately\fP obvious that an assignment or index is incorrect.
E.g. ``monthNext\ \=\ yearLast'' is clearly wrong.
.LI
Reduction and/or elimination of name conflicts.
Two things (variables or whatever) can only have the same name if
they are in fact the same thing.
.LI
Decrease in name choosing time.
Since the ``creativity'' has been removed, names are not \fIchosen\fP
\- they are constructed.
.LI
Enhanced readability/maintainability of the code.
Since all programmers working on a project are using the \fIsame\fP
naming convention, where one person leaves off and another starts
is not only \fIvisually\fP undetectable, it often becomes
\fIemotionally\fP less important to the programmers involved.
This reduces intra-group finger pointing, etc.
.LE
.sp 1
.P
\fBRules of Name Construction\fP
.AL 1
.LI
All variable names start with a lower case letter.
E.g. foo.
.LI
All function names start with an upper case letter.
E.g. Procedure.
.LI
Variables, and functions that return a value, start with the
a 1 to 4 character type specifier.
E.g. fooLast and FooFromAdr.
.LI
Variable names may have 0 or more trailing modifiers to indicate
their particular usage in the current context.
E.g. foo, fooFirst, fooFirstKludge.
.LI
All global variables have the character `v' prepended.
E.g. vfooNext.
Historically, the `v' meant ``virtual''.
.P
NOTE:  Although manifest constants are
.SM NOT
distinguished by all upper case, this does not cause a problem.
If what looks like
a variable does not begin with `v',
and it is not defined in the current procedure, it
.SM MUST
be a constant.
.LE
.P
The rules for constructed TYPES are:
.AL 1
.LI
All type names, other than primitives of the language (e.g. char),
have a base type that is all upper case.
E.g. typedef char * ADRT.
.LI
The last letter indicates the `class' of the type.
Specifically:
.LE
.VL 13 4
.LI T
means that this Type is simply a different name for one of the
language primtives.
(e.g. typedef char FLAGT;)
.LI S
means that the type is a Struct.
(e.g. struct FOOS {int x;};).
.LI R
means that the type is a Record (struct in C).
(e.g. typedef struct FOOS FOOR;).
.LI U
means the type is a Union.
.LI E
means an Enumerated type.
This notation is also used with `#define'd values if their usage is
the same as enums.
E.g. a storage class might look like:
.DS
typedef enum {scText, scData, scBss} SCE;
.DE
.LI p
Pointers occur for many types and are constructed by prepending
a lower case `p' to the type name.
.DS
typedef FOOR *pFOOR; /* creates the type `pointer to FOOR' */
.DE
.LE
.P
There are certain concepts that appear repeatedly.
These often are simple types such as `index' or `count' that may
apply to all sorts of situations.
Examples are shown below.
The declared type is \fIint\fP unless shown in ()'s.
.VL 13 4
.LI cApples
Count of apple's.
.LI ifoo
Index of foo's.
.LI dx
The first Difference of x. (dx = xFirst - xLast)
.LI cbFoo
Count of Bytes in foo.
.LI cbFOOR
Count of bytes in a record of type FOOR.
This is normally `#define cbFOOR sizeof(FOOR)'.
.LI chFoo
Character relating to a Foo. (char)
.LI sbFile
String of bytes (character string).
(char *sbFile OR char sbFile[10])
.LI fDidit
A flag (boolean).
(smallest type available OR 1 bit field)
.LE
.P
Modifiers may be added to clarify the usage of a particular value.
Certain modifiers have well defined meanings.
These are:
.VL 13 4
.LI fooNil
A standard Nobody-Home value for foo.
Depending on
FOO, this may be -1, 0, ((pFOOR)0), or ???.
This value is almost guaranteed to be `#define'd.
.LI fooFirst
First foo value.
For all foo, fooX >= fooFirst.
.LI fooLast
Last foo value.
For all foo, fooX <= fooLast.
.LI fooMin
Minimum value of foo.
For all foo, fooX >= fooMin.
.LI fooLim
Limit of foo.
For all foo, fooX < fooLim.
Used for
non-index type values.
.LI ifooMax
Maximum value of ifoo.
For all foo, fooX < fooMax.
Used mostly in the form `ifooMax'.
This value is almost always `#define'd.
An exception is the size of dynamic arrays.
.LI ifooMac
The Current maximum ifoo value.
When ifoo is the domain of an array used as a stack,
ifooMax is the total size, and ifooMac is what we are currently using.
ifoo < ifooMac <= ifooMax.
.LE
.P
Values in some sequence may be modified by:
fooPrev, fooInit, fooLow, fooHigh, fooNext, fooOld, fooNew, etc.
.P
The conventions for array declarations are:
.VL 13 4
.LI mpBarFoo
an array (MaP) with domain BAR and range FOO.
E.g. fooX = mpBarFoo[barFirst];
.LI rgFoo
an array with domain `ifoo' and range FOO.
E.g. fooX = rgFoo[ifoo];
.LE
.sp 1
.P
\fBProcedures\fP
.P
Procedure names are inherently more complex and the conventions are less rigid.
If a value is returned, it is always the first part of the name.
The letter `F' indicates a mapping From the arguments to the return value(s).
The 1 or 2 most important arguments occur after the 'F'.
E.g. IpdFAdr(adr) returns an Index into the Procedure Descriptor array
as a function of an ADdRess.
.P
In the case where some arguments are being passed by reference, these
are always the first in the argument list, mimicing the ordering in the
assignment statement.
.P
If there is no return value, then the name is composed of an imperative verb
(Do, Get, Put, Print, etc.) followed by the first one or two argument
types (PutCh, PrintLine, etc.).
.bp
.P
\fBExamples\fP
.P
The following examples show how the naming conventions work together.
.sp 1
.nf
.cs 1 21
typedef char *ADRT;              /* an address type of some sort */
#define adrNil ((ADRT)0)         /* standard nil value */

typedef enum {fsNil,             /* foo state */
              fsActive,
              fsDead
              } FSE, *pFSE;

typedef struct FOOS {            /* the FOO structure */
        ADRT    adrFirst;
        ADRT    adrLast;
        struct FOOS *fooNext;    /* essentially of type pFOOR */
        FSE     fs;
        } FOOR, *pFOOR;
#define cbFOOR sizeof(FOOR)
#define fooNil ((pFOOR)0)        /* standard nil value */

#define ifooMax 100              /* size of foo array */
FOOR    vrgFoo[ifooMax];         /* global array of foo's */
int     vifooMac;                /* how many foo's we are currently using */

ADRT AdrFFoo(foo)
pFOOR   foo;
{
    if (foo->fs == fsActive)     /* some random computations */
        return(foo->adrFirst);
    return(adrNil);
}

void FreeFoo(foo)                /* does NOT return a value */
pFOOR   foo;
{
    /* deallocate in some way... */
    foo->fs = fsDead;
}
.fi
