From: lwall@netlabs.com (Larry Wall)
Newsgroups: comp.lang.perl
Subject: Re: Perl language formatting conventions?
Date: 27 Aug 92 04:29:32 GMT
Distribution: comp
Organization: NetLabs, Inc.

In article <1992Aug25.224912.1775@news.eng.convex.com> tchrist@convex.COM (Tom Christiansen) writes:
: Here's the Berkeley style guide for comparison.  I don't personally
: use all of them (i.e. I use 4-space indents and test pointers with 
: a raw "if (p)') but surprisgnly, I find that many I do use even 
: though I had never read this guide.

I also use 4-space indent, in case you hadn't noticed.  :-)

I'm gonna comment on some of these C thingies, so if you're here to read
about Perl formatting you can type "n" now.

: /*
:  * Macros are capitalized, parenthesized, and should avoid side-effects.
:  * If they are an inline expansion of a function, the function is defined
:  * all in lowercase, the macro has the same name all in uppercase. If the
:  * macro needs more than a single line, use braces.  Put a space before
:  * the backslashes.
:  */
: #define	MACRO(x, y) { \
: 	variable = (x) + (y); \
: 	line two; \
: }

I'd line up the backslashes--it's an awful lot easier to see when you've
left one out.

: /* Enum types are capitalized. */
: enum enumtype { ONE, TWO } et;

Those are enum *values*, not types.

: /*
:  * When declaring variables in structures, declare them sorted by use, then
:  * by size, and then by alphabetical order.  The first category normally
:  * doesn't apply, but there are exceptions.  Each one gets its own line.
:  * Put a tab after the first word, i.e. use "int^Ix;" and "struct^Ifoo *x;".
:  *
:  * Major structures should be declared at the top of the file they are
:  * used in, or in separate header files, if they are used in multiple
:  * source files. Use of the structures should be by separate declarations
:  * and should be "extern" if they are declared in a header file.
:  */
: struct foo {
: 	struct	foo *next;	/* List of active foo */
: 	struct	mumble amumble;	/* Comment for mumble */
: 	int	bar;
: };
: struct foo *foohead;		/* Head of global foo list */

What they didn't say was that you sort the variables in structures
by *decreasing* size.  This makes for the most compact representation
without the compiler cheating on the semantics of C.

I also think it's silly to put the tab between "struct" and the type
name.  I'm of two minds as to where to put the tab on pointers to
structures.  Sometimes I put

	struct foo	*next;

and sometimes

	struct foo*	next;

depending on how heavily I'm into denial over C's type syntax.  I've
been doing more of the latter lately.

: 	while ((ch = getopt(argc, argv, "abn")) != EOF)
: 		switch (ch) {		/* Indent the switch. */
: 		case 'a':		/* Don't indent the case. */
: 			aflag = 1;
: 			/* FALLTHROUGH */
: 		case 'b':
: 			bflag = 1;
: 			break;
: 		case 'n':
: 			num = strtol(optarg, &ep, 10);
:                         if (num <= 0 || *ep)
:                                 err("illegal number -- %s", optarg);
: 			break;
: 		case '?':
: 		default:
: 			usage();
: 		}

This is evil.  Any dangled statement longer than one line should be
enclosed in braces.  One of the reasons I require braces in Perl...

: 	/*
: 	 * Space after keywords (while, for, return, switch).  No braces are

Yes.  I don't want my keywords looking like functions, and vice versa.

: 	 * used for single statement block.
: 	 *
: 	 * Forever loops are done with for's, not while's.
: 	 */
: 	for (;;)
: 		stmt;

Yes, I find the (;;) visually distinctive for a distinctive idea, and
C needs all the visual distinctiveness it can muster.

: 	/*
: 	 * Try to put shorter part first.  The closing and opening braces
: 	 * go on the same line as the else.
: 	 */
: 	if (test)
: 		stmt;
: 	else if (bar) {
: 		stmt;
: 		stmt;
: 	} else
: 		stmt;

I prefer my else's to line up, but that's just taste.  Whether to put
the shorter part first depends on how easy it is to express the conditional
in an understandable way.  Sometimes I go so far as to change the name
of a Boolean variable so that I can put the right branch first without
extra !'s.  The real trick is to find the opposite name for the Boolean
variable without just putting "no" on the front of it...  :-)

: 	/* No space after function names. */
: 	if (error = function(a1, a2))
: 		exit(error);

Yes.  I don't want my keywords looking like functions, and vice versa.
The parens of a function are an intrinsic part of the function call in C.
Pretending that a function name is a unary operator prefixing an ordinary
parenthesized list is bogus to me.

: 	/*
: 	 * Unary operators do not require spaces, binary operators do.
: 	 * Try not to use too many parenthesis unless the statement is
: 	 * really confusing without them.
: 	 */
: 	a = b->c[0] + ~d == (e || f) || g && h ? i : j >> 1;
: 	k = l & FLAGS;

Hmm, sometimes you just need to break up an expression and indent it
reasonably.  Sometimes you can omit the spaces on a binary operator to
imply precedence:

	a + b*c + d;

: 	/*
: 	 * Exits should be 0 on success, and 1 on failure.  Don't denote
: 	 * all the possible exit points, using the integers 1 through 300.
: 	 */
: 	exit(0);    /* Avoid obvious comments such as "Exit 0 on success." */

Obviously, you have to get along with Unix here, but for return values
I prefer "success" to be associated with "truth".  You can pass the
(presumably infrequent) error information by some other mechanism when
necessary, and then you won't be tempted to shoehorn too much meaning
into a simple-minded integer.

: /*
:  * If a function type is declared, it should be on a line
:  * by itself preceeding the function.
:  */
: static char *
: function(a1, a2, a3, a4)

Yes, and notice that they're doing a line break where earlier I said
I liked doing a tab--after the *.  But of course, the reason is
rather different here.  We want to be able to search using /^function.

: 	int a1, a2, a4;	/* Declare ints too. */

I'd put these on separate lines.

: 	/*
: 	 * Casts and sizeof's are not followed by a space.  NULL is any
: 	 * pointer type, and doesn't need to be cast, so use NULL instead
: 	 * of (struct foo *)0 or (struct foo *)NULL.

This can break when passing arguments to functions.  I prefer to use
typed NULLish thingies for documentation purposes consistently, and
then I don't forget to cast them when I use them as function
arguements.  So I end up with Nullch, Nullfp, etc, or in the general
case, Null(FOO*).

: 	 * Also, test pointers against NULL, i.e. use:
: 	 *
: 	 * 	(p = f()) == NULL
: 	 * not:
: 	 *	!(p = f())

NO!  This is a throw-back to Pascal, in which conditionals require
Boolean values and only Boolean values.  C blesses the notion that many
types can be used as Boolean values.  C++ carries this even further,
and essentially provides that any user-defined type for which it makes
sense can be set up to be used as a Boolean value.

:  	 *
: 	 * Routines returning void * should not have their return values cast
: 	 * to any pointer type.
: 	 */
: 	if ((four = malloc(sizeof(struct foo))) == NULL)
: 		return (NULL);

That's contrary to usual industry practice.  Fortunately the necessity
for it goes away in C++.

: 	if ((six = (int *)overflow()) == NULL)
: 		return (NULL);
: 	return (eight);

Of what earthly good are the parens around a return value, other than to
make Yet Another Keyword look like a function?

Well, enough of that.  Back to your regularly scheduled programming.

Larry