Coding Convention

  1. Internal documentation
    • begin every predicate (except auxiliary predicates) with an introductory comment in the standard format. % remove_duplicates(+List, -ProcessedList) % % Removes the duplicates in List, giving ProcessedList
    • Use descriptive argument names in the introductory comment; they need not to be the same as those in the clauses.
  2. Predicate names
    • Make all names pronounceable
    • Never use two different names that are likely to be pronounced alike: if you use foo, do not also use foo_ or fu
    • Construct predicate names with lower-case, sparating words with underscores: is_well_fomred
    • Do not mix up to, two, and too
    • Within names, do not express numbers as words.
    • Identify auxiliary predicates by appending _aux or _x, _xx and so forth: if you name your main predicate foo and need an auxiliary predicate, then name it foo_aux or foo_x
    • If a predicate represents a property or relation, its name should be a noun, noun phrase, adjective, prepositional phrase, or indicative verb phrase.
    • If a predicate is understood procedurally - that is, its job is to do something, rather than to verify a property - its name should be an imperative verb phrase: remove_duplicates
    • Place arguments in the following order: inputs, intermediate results, and final results.
    • Consider how your arguments map onto ordinary English: ex. mother_of(A,B) is ambiguous. Naming it mother_child would eliminate the ambiguity.
  3. Variable names
    • Use descriptive names for variables whereever possible, and make them accurate.
    • Construct variable names with mixed-case letters, using capitalization to set off words: for ex. write ResultSoFar, not Result_so_far
    • For variables of purely local significance, use single letters: I, J, K, L, M, N for integers, L, L1,L2,... for lists; A, B, C,..., X, Y, Z for arbitrary terms; H and T for head and tail of a list.
    • Use a single letter for the first element of a list and a plural name for the remaining elements: for ex. a list of trees: [T|Trees]
  4. Layout
    • Indent all but the first line of each clause.
    • If a test is unnecessary because a cut has guaranteeed that it is true, say so in a comment at the appropriate place.
    • Indent an additional 2 spaces between repeat and the corresponding cut.
    • Put each subgoal on a separate line, except closely related pairs such as write and nl
    • Skip a line between clauses, Skip two lines between predicates.
    • Keep clauses less than 25 lines if possible
    • Consider redesigning any non_auxiliary predicate that has more than 4 arguments.
    • Consider using a prettyprinter for finished printouts.
  5. Expresing algorithms
    • When efficiency is critical, make tests.
    • Conduct experiments by writing separate small programs, not by mangling the main code.
    • Use cuts springly but precisely.
    • Never add a cut to correct an unknown problem
    • 'Avoid the semicolon (;) - make separate clauses instead.
    • Use parentheses whenever operator precedence is important.
    • When you sue ; always use parentheses.
    • Avoid if-then-else structure because that is a rather un-Prolog-like way of thinking.
    • Avoid append as far as possible
    • Use difference lists to achieve fast concatenation
    • Use tail recursion for recursions of unknown depth.
  6. Reliability
    • Isolate non-portable code.
    • Isolate "magic numbers": if a number occurs more than once in your program, make it the argument of a fact.
    • Test code at its bounderies
    • Test that each loop starts correctly, advances correctly, and ends correctly.
    • Test every predicate by forcing it to backtrack: for ex. count_up(5), fail.
    • Test predicates by supplying arguments of the wrong types.
    • Make error messages informative: Where, What, How
    • Use the logging library: logging(module,Text,[Variables]).
    • Add logging(Module,'',[Variables]) for the begin of a prediacte and logging(Module,'',[Variables]) for the end of the predicate.
    • Mark all temporarily altered lines of code with %TEST
    • Use write('!!!') to mark places in the program where work remains to be done.

-- LeNguyenThinh -- 30 Jun 2005
 
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding Foswiki? Send feedback