You should use a two-space indentation. Each time code needs to be further indented, you should use one indent level, which is two spaces.
When a slot description wraps to a new line in a "define class" form, the extra lines should be indented one extra indent level.
If you use /// comments, they should only be used between top-level declarations. /// comments can be used for logical page headers, inter-function comments, code section introductions (logical page headers), etc., for example:
... end method; /// order-espresso -- Method for Exported GF. /// /// This method orders espresso at carts on the corner when it is /// raining. If it is not raining, this method delegates to /// next-method. /// define method order-espresso (vendor :: <outdoor-espresso-cart>, #next next-method) => (); ... end method;
Many programmers do not like others to use /// comments. Rob noted that if these are only used between top-level declarations, where the /// indicates a comment of wider scope (as over a whole definition or logical page), then the Gwydion environment should be able to display such comments however any particular user wants to see them.
If you use /* ... */ comments, they should only be used at the beginning of a file or the beginning of a logical page so that their use is highly localized. This prevents them from showing up surprisingly in random places throughout a file of code. Using /*...*/ comments should go away once the Gwydion environment has a means for linking general commentary to logical units of code. This issue has absolutely nothing to do with using /*...*/ to temporarily exclude code fragments.
When a function header wraps (that is, a define generic or a define module declaration), you should either break the line within the parameter list or between the name and the parameter list. If you break the line between the name and parameter list, or perhaps after the parameter list, then you should indent any extra lines one extra indent level. There is one exception: the first line of the return values specification may be indented only one space. The following are examples of recommended style:
define method some-longer-name-for-effect (one :: <class-1>, two :: <class-2>, ...) => (result1 :: <type1>, result2 :: <type2>); statement1; statement2; ...; end method; define method some-longer-name-for-effect (one :: <class-1>, two :: <class-2>, ...) => (result1 :: <type1>, result2 :: <type2>); statement1; statement2; ...; end method;
If there is more than one keyword parameter specified in a function declaration, then all keyword parameter specifications should line up with the first specification. The following is an example:
define method foo (foo :: <simple-object-vector>, #key start :: <fixed-integer> = 0, stop :: <fixed-integer> = foo.size) ...
If a parameter list that contains a #key wraps, then you should wrap the parameter list before the #key token.
When a variable or constant definition wraps, you should break the line before the = token:
define constant western-culture :: <integer> = north-america-mask | south-america-mask | europe-mask;
You should use end mumble, rather than just end, whenever there is sufficient vertical space between the beginning and the end of the statement to hinder readability. Some programmers like to use end mumble religiously, but those same programmers only use "end" when using end mumble would make a single-line statement wrap onto a new line. Programmers may add the mumble to an end if they feel the code was hard to visually scan, but programmers should not add mumbles to all ends in someone else's code just because they like that style. This policy is consistent with adding additional comments to someone else's code to help readability.
You should NOT use horizontal spacing to columnize aspects of Dylan code, or to present other visual effects within the program. If you do this, you should do it rarely. The one exception to this rule is the "Indent keyword parameters beyond #key token" recommendation.
You should only use keyword notation for symbols in function calls and function declarations. You can also use keyword notation in slot descriptions within define class, where you are supplying a symbol to be the key for an initialization argument. When a symbol is a value, such as a default value in a declaration or an argument value in a call, you should use symbol notation, not keyword notation. The following are examples of recommended style:
define method reposition (stream :: <stream>, offset :: <integer>, #key from: = #"start") define method foo () ... bar(x, y, color: #"red"); ... end method; // In this example, required-init-keyword: would always be in // keyword notation, and "foo:" is the item to which this style // recommendation speaks. // define class <frob> slot gag, required-init-keyword: foo:; end; // // Or ... // define class <frob> slot gag, required-init-keyword: #"foo"; end;
You should include a blank comment line between the introductory comments for a function and the function definition. This applies to any top-level declaration for which you supply an introductory comment. The following is an example:
// Blah blah blah GINGER blah blah blah. // define ...
If any single branch of a case statement wraps, then you should wrap every branch. In practice, there are common exceptions to this recommendation.
When wrapping a case statement, you should wrap it after the => token. There should be no exceptions to this recommendation.
The following exhibit the recommended style:
case test1 => expression1; test2 => expression2; end; case test1 => statement1; statement2; test2 => statement1; statement2; end;
You should not use #t for otherwise in case statements.
When an =/then clause needs to wrap, you should wrap before the = and before the 'then'. Both the '=' and the 'then' should be indented one extra indent level:
// Correct. // ... nested levels ... for (some-index = initialization-expression(x, y, z) then stepper(u, v, w)) stuff(some-index); end; // Incorrect. // ... nested levels ... for (some-index = initialization-expression(x, y, z) then stepper(u, v, w)) stuff(some-index); end;