Code Formatting

From wiki.visual-prolog.com

Jump to: navigation, search

Contents

Code Formatting

This document describes coding standards for Visual Prolog programs, written as part of the Visual Prolog system itself. It is also the standards for examples in user documentation. As such, it represents Prolog Development Center's suggested coding standards for users as well.

Keywords

Keywords are typed in lower-case letters. In documents keywords are typeset with a sans serif font, for example Arial. Default color is dark yellow.

constants
domains
facts
predicates
class
interface
...


Semi-keywords

Visual Prolog uses a number of tokens for diverse syntactical structuring. These words are all written in lower-case normal faced sans serif font. These semi-keywords are colored in two different colors depending on their nature. If the word represents a choice then it is colored navy, whereas if it is a structuring word, it is colored dark yellow.

erroneous
failure
procedure
determ
nondeterm
multi
language
as
stdcall
c
...

This example shows the colors and the font:

predicates
    myPredicate : (string Value) procedure (i) language stdcall as "_myP"

Literals

Literals are colored blue.

1
"Hello world!"


Identifiers

The general format of an identifier can be described by the following EBNF grammar:

<Identifier> = <Prefix> <WordGroups> <Suffix>
<WordGroups> = <WordGroup> { ‘_’ <WordGroup> }*
<WordGroup> = <Word>+

Prefixes and suffixes are used to signal the kind of identifier, and will be dealt with in connection with each kind of identifiers. The words are capitalized, except for those situations, where the first letter of the whole identifier has to be lower case.

All variables start with an uppercase letter and everything else starts with a lower case letter.

In documents everything except keywords are typeset in a serif font, for example Times New Roman

Constants

Constants have got no prefix or suffix. They start with a lowercase letter.

numberOfRows
pi
logErrorMsg


Variables

Variables have got no prefix or suffix. As mentioned (and demanded by Prolog) variables start with an uppercase letter. In documents variables are colored green.

X
File
OutputStream


Predicates

Predicates have got no prefix. However, "try", "is", "has" and the like can be used to signal that a predicate is determ, and it is especially used to distinguish a determ version of a predicate from a corresponding procedure version, where the latter will raise an exception instead of failing. For example:

trySetValue : (integer Value) determ (i).
setValue : (integer Value) procedure (i).

isXxxx and hasXxxx are good choices for test predicates (provided the name makes sense of course).

Predicates have got no suffixes, unless it seems to be necessary in order to avoid confusion. In such cases the following suffixes should be preferred:

  • _fact nondeterm fact
  • _nd nondeterm/multi
  • _err erroneous
  • _fail failure
  • _dt determ
  • _multi multi Notice, that normally multi predicates would be suffixed with _nd, but if circumstances demand it _multi can be used instead.
setWindowFont
member
member_nd
ganttBar_fact

Domains

Domains have got no prefix. _list is used as suffix to list domains, in the cases, where the list domain does not have a (business-)domain name, i.e. a database record is a list of values, but record is a better domain name that value_list, so that is preferred. Notice that domains start with a lowercase letter. This also holds for build-in domains like string, integer, etc.

string
value
record
record_list


Classes and Interfaces

Classes and interfaces have got no prefix.

string
inputFile
template
inputStream

COM interfaces traditionally start with an "I", this "I" is kept but converted to lowercase:

iUnknown
iDispatch

Formatting

This section considers formatting of program code. By formatting we mean line breaking, indentation and alignment. Indentation refers to the amount of white space at the beginning of the line, where as alignment refers to aligning constructs which are not the first on the line.

Line breaking

Line breaking follows the following rules:

  • Outer syntactic constructs are in general broken before inner constructs.
  • At least one empty line separates clauses of different predicates.
  • Clauses of the same predicate can be separated by an empty line.
  • At least one empty line precedes a section keyword.
  • If predicate call is not nested, then it is on a line by itself.
  • Cut (no matter how tiny it seems) is also on a line by itself.
  • The head of a clause is on a line by itself. But the return value of a function clause may start on that line.

Indentation

By indentation we mean the amount of white space at the beginning of the line. Indentation follows the following rules:

  • Indentation is done in equal steps (for example 4 spaces).

Alignment

No alignment is used (alignment refers to aligning constructs which are not the first on the line, constructs which are the first on the line are "aligned" by indentation rules).

Space characters

  • Space after comma.
  • Space after comma can be omitted inside functors, including lists.
  • Space before and after ':' in the declaration of a predicate, a fact, a constant.
  • No spaces before or after parentheses, unless the parenthesis is next to a token that is normally surrounded by space, such as ' :- ', ' : '

Constructs

In this section we shall deal with constructs one by one.

Sections

Section keywords are on a line by itself. A section keyword is not indented. The constructs of the section are indented one step. Sections must be separated by at least one empty line.

clauses 
    p.
 
clauses
    q.


Classes, Interfaces, Implementations, etc

The class opening and class closing is on a line by itself. The closing always includes the class identifier, the section keywords inside the class are not indented.

class specialOutputFile : outputFile
predicates
    ...
end class specialOutputFile

The same goes for other constructs like class (i.e. interface, implement).

Predicate declarations

Predicate declarations always have names for the arguments; these names are formatted as variables. procedure mode declaration is omited.

predicates
    increment : (integer X) -> integer Y.
    bubbleSort : (integer_list Input) -> integer_list SortedList.
    myPredicate_nd : (
            aVeryLongDomainName StrangeFirstParamanter, 
            anotherLongDomainName PlainSecondParameter)
        nondeterm (i,o)
        determ (i,i).

Notice the line break after the opening parenthesis and the ordinary increase in indentation.

Domains

Functors always have names for their arguments; these names are formatted as variables. If a domain declaration is broken on several lines then it is first broken after the equal sign. Either all functors are on a single line or each of them is on a separate line. Either all arguments of a functor are on a single line or each of them is on a separate line.

domains
    value =
        int(integer Value);
        real(real Value);
        str(string Value).
 
domains
    aVeryLongDomainName =
        x(integer X); y(integer Y).
 
domains
    anotherLongDomainName =
        aFunctorWithManyArguments(
            integer X,
            integer Y,
            integer Z,
            integer RedColourComponent,
            integer BlueColourComponent,
            integer GreenColourComponent).

Clauses

The clause head is on a line by itself. Each call in the clauses body is on a line by itself. If clause head have to be broken then the arguments are indented two steps more than the clause head, because otherwise it would be indented to the same position as the clause body.

clauses
    myPredicate(X, Y) :-
        callNoOne(X, Y, Z),
        !,
        callNoTwo(Z, Y).
    myPredicate(X, Y) :-
        callNoThree(X, Y).
 
clauses
    aPredicateWithManyArguments(FirstArgument, SecondArgument,
            X, Y, Z, ErrorNo, ErrorMsg) :-
        callNoOne(FirstArgument, SecondArgument, X, Y, Z,
            ErrorNo, ErrorMsg),
        callNoTwo(),
    …

Non-deterministitic Loops

A construction that is often used in Prolog is "looping" over the results of a non-deterministic call. For this construction we propose to indent the "loop body" one extra level:

clauses
    myPredicate() :-
        member(X, [1,2,3,4,5,6]),
            doAction(X), % extra indentation in the "loop body"
        fail.
    myPredicate().

You should use foreach where possible.


References

Personal tools