Difference between revisions of "User:Kai Burghardt/Style guide"
From Lazarus wiki
Jump to navigationJump to search (→naming scheme: more example) |
(remove legacy syntaxhighlight syntax; emphasize a point; typography) |
||
Line 7: | Line 7: | ||
: Do not write snake-case identifiers, unless they originate from foreign libraries (probably written in C) | : Do not write snake-case identifiers, unless they originate from foreign libraries (probably written in C) | ||
; names optionally follow a hierarchy | ; names optionally follow a hierarchy | ||
− | : E.g. there are the range types <syntaxhighlight lang="pascal" | + | : E.g. there are the range types <syntaxhighlight lang="pascal" inline>fooDomain</syntaxhighlight> and <syntaxhighlight lang="pascal" inline>fooCodomain</syntaxhighlight>, both starting with <syntaxhighlight lang="pascal" inline>foo</syntaxhighlight>. Or, in another example, there are <syntaxhighlight lang="pascal" inline>staffMember = record … end;</syntaxhighlight> and <syntaxhighlight lang="pascal" inline>staffMemberReference = ^staffMember;</syntaxhighlight>, both starting with <syntaxhighlight lang="pascal" inline>staffMember</syntaxhighlight>. So related identifiers could appear next to each other in an alphabetical listing of them. But do not enforce this idea. |
+ | : Note: Unit scopes and namespaces automatically form a hierarchy. Ensure the ''fully qualified'' identifier does ''not'' contain any redundancies. Counter example: {{Doc|package=RTL|unit=mouse|identifier=showmouse|text=<syntaxhighlight lang="pascal" inline>showMouse</syntaxhighlight>}} in the {{Doc|package=RTL|unit=mouse|text=<syntaxhighlight lang="pascal" inline>mouse</syntaxhighlight> unit}}. The fully-qualified identifier is <syntaxhighlight lang="pascal" inline>mouse.showMouse</syntaxhighlight>. The word “mouse” appears twice. This is not nice. A better name for the procedure would have been (using the same verb) just <syntaxhighlight lang="pascal" inline>show</syntaxhighlight>. If the programmer using the unit needed or wanted to emphasize what element is being shown, he could write the fully qualified identifier. | ||
; Do not abbreviate within identifiers. At no point, ever. | ; Do not abbreviate within identifiers. At no point, ever. | ||
− | : Being lazy and abbreviating (or worse), does not improve readability. Although it is tedious to spell out everything, it will serve you well when revisiting code that | + | : Being lazy and abbreviating (or worse), does not improve readability. Although it is tedious to spell out everything, it will serve you well when revisiting code that hasn’t been seen for months. Don’t save money in the wrong place. Properly named identifiers are a case in point. |
; plural nouns refer to collections, singular nouns to individual objects | ; plural nouns refer to collections, singular nouns to individual objects | ||
− | : e.g. there is an enumeration type <syntaxhighlight lang="pascal" | + | : e.g. there is an enumeration type <syntaxhighlight lang="pascal" inline>mode</syntaxhighlight>, then the data type <syntaxhighlight lang="pascal" inline>modes</syntaxhighlight> – ''plural'' – will refer to a <syntaxhighlight lang="pascal" inline>set of mode</syntaxhighlight> (or other sort of collection) |
== LOC == | == LOC == | ||
; Indent with tabulators. | ; Indent with tabulators. | ||
: They take one byte, versus two or more bytes for spaces. | : They take one byte, versus two or more bytes for spaces. | ||
− | ; Always write <syntaxhighlight lang="pascal" | + | ; Always write <syntaxhighlight lang="pascal" inline>begin</syntaxhighlight> and <syntaxhighlight lang="pascal" inline>end</syntaxhighlight> where it is allowed. |
: This will minimize risks of erroneously thinking something belongs to a certain language construct. | : This will minimize risks of erroneously thinking something belongs to a certain language construct. | ||
− | : Even [[Repeat|<syntaxhighlight lang="pascal" | + | : Even [[Repeat|<syntaxhighlight lang="pascal" inline>repeat … until</syntaxhighlight>]] have their own <syntaxhighlight lang="pascal" inline>begin … end</syntaxhighlight> even though it is redundant. |
; Unary operators are not separated by a space from their operand, unless it is a word. | ; Unary operators are not separated by a space from their operand, unless it is a word. | ||
− | : Otherwise one could write <syntaxhighlight lang="pascal" | + | : Otherwise one could write <syntaxhighlight lang="pascal" inline>40 - - 2</syntaxhighlight> which just looks ridiculous. |
; Binary operators are surrounded by a single space on each side. | ; Binary operators are surrounded by a single space on each side. | ||
− | : Otherwise one could write <syntaxhighlight lang="pascal" | + | : Otherwise one could write <syntaxhighlight lang="pascal" inline>40--2</syntaxhighlight>. I don’t like that. Write <syntaxhighlight lang="pascal" inline>40 - -2</syntaxhighlight> and we’re friends. |
; An opening parenthesis starting the parameter list always follows directly the identifier. | ; An opening parenthesis starting the parameter list always follows directly the identifier. | ||
− | : Do not write <syntaxhighlight lang="pascal" | + | : Do not write <syntaxhighlight lang="pascal" inline>writeLn (42)</syntaxhighlight>. The parameters “belong” to the identifier, thus ought to be right next to them. Write <syntaxhighlight lang="pascal" inline>writeLn(42)</syntaxhighlight> with no blank inbetween and we’re good. |
== design == | == design == | ||
Line 33: | Line 34: | ||
foo := x + 7; | foo := x + 7; | ||
end;</syntaxhighlight> | end;</syntaxhighlight> | ||
− | : While you | + | : While you don’t necessarily use range and overflow checks in a production program, Pascal allows you to thwart many errors already at compile-time. In general, define domains and co-domains of routines in a manner, where they are actually defined. That means for the example above |
<syntaxhighlight lang="pascal">type | <syntaxhighlight lang="pascal">type | ||
fooDomain = 0..high(qWord)-7; | fooDomain = 0..high(qWord)-7; | ||
Line 44: | Line 45: | ||
== see also == | == see also == | ||
− | * [[DoDont| | + | * [[DoDont|Do’s and Don’ts]] |
* [[Coding style]], [[DesignGuidelines|design guidelines]], [[Nomenclature]] | * [[Coding style]], [[DesignGuidelines|design guidelines]], [[Nomenclature]] | ||
− | [[Category:Coding style]] | + | [[Category: Coding style]] |
Revision as of 00:53, 2 May 2020
naming scheme
- no Hungarian notation
- Hungarian notation is the naming style, where identifier start with letters associated with certain type categories. Always give meaningful names.
- camel-case identifiers
- Pascal is case-insensitive.
- Identifiers do not contain underscores.
- Do not write snake-case identifiers, unless they originate from foreign libraries (probably written in C)
- names optionally follow a hierarchy
- E.g. there are the range types
fooDomain
andfooCodomain
, both starting withfoo
. Or, in another example, there arestaffMember = record … end;
andstaffMemberReference = ^staffMember;
, both starting withstaffMember
. So related identifiers could appear next to each other in an alphabetical listing of them. But do not enforce this idea. - Note: Unit scopes and namespaces automatically form a hierarchy. Ensure the fully qualified identifier does not contain any redundancies. Counter example:
showMouse
in themouse
unit. The fully-qualified identifier ismouse.showMouse
. The word “mouse” appears twice. This is not nice. A better name for the procedure would have been (using the same verb) justshow
. If the programmer using the unit needed or wanted to emphasize what element is being shown, he could write the fully qualified identifier. - Do not abbreviate within identifiers. At no point, ever.
- Being lazy and abbreviating (or worse), does not improve readability. Although it is tedious to spell out everything, it will serve you well when revisiting code that hasn’t been seen for months. Don’t save money in the wrong place. Properly named identifiers are a case in point.
- plural nouns refer to collections, singular nouns to individual objects
- e.g. there is an enumeration type
mode
, then the data typemodes
– plural – will refer to aset of mode
(or other sort of collection)
LOC
- Indent with tabulators.
- They take one byte, versus two or more bytes for spaces.
- Always write
begin
andend
where it is allowed. - This will minimize risks of erroneously thinking something belongs to a certain language construct.
- Even
repeat … until
have their ownbegin … end
even though it is redundant. - Unary operators are not separated by a space from their operand, unless it is a word.
- Otherwise one could write
40 - - 2
which just looks ridiculous. - Binary operators are surrounded by a single space on each side.
- Otherwise one could write
40--2
. I don’t like that. Write40 - -2
and we’re friends. - An opening parenthesis starting the parameter list always follows directly the identifier.
- Do not write
writeLn (42)
. The parameters “belong” to the identifier, thus ought to be right next to them. WritewriteLn(42)
with no blank inbetween and we’re good.
design
- use the strong typing system to your advantage
- Consider the following “wrong” piece of code (on a 64-bit platform):
function foo(const x: qWord): qWord;
begin
foo := x + 7;
end;
- While you don’t necessarily use range and overflow checks in a production program, Pascal allows you to thwart many errors already at compile-time. In general, define domains and co-domains of routines in a manner, where they are actually defined. That means for the example above
type
fooDomain = 0..high(qWord)-7;
fooCodomain = 7..high(qWord);
function foo(const x: fooDomain): fooCodomain;
begin
foo := x + 7;
end;
- Of course this is a trivial example, but consequently employing this technique makes it possible to spot errors via simple range checks. (see also tutorial: defensive programming techniques)