Talk:CodingStandards: Difference between revisions
→Passing an argument by value: new section |
IanMcGowan (talk | contribs) mNo edit summary |
||
(5 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
== Using a code formatter == | |||
One general statement - it's one thing to write a document that all programmers on your system *should* follow. To make sure all these great ideas *are* followed, I'd encourage creating a formatter/linter/pre-compiler specific to your needs and embedding that in your pipeline for moving code from dev->test->prod. Not everything can be enforced, but hard and fast rules can and should be automatically applied. | |||
== Ternary assignment preferred == | |||
Regarding 2.10 "Avoid using obscure and unfamiliar coding styles", the example shows ternary assignment as "BAD"; that is, obscure and unfamiliar to most PICK programmers. I actually prefer to use ternary assignment instead of multi-line IF-THEN-ELSE logic. Ternary assignment helps to avoid the error where the variable name is mis-typed in the ELSE clause. | Regarding 2.10 "Avoid using obscure and unfamiliar coding styles", the example shows ternary assignment as "BAD"; that is, obscure and unfamiliar to most PICK programmers. I actually prefer to use ternary assignment instead of multi-line IF-THEN-ELSE logic. Ternary assignment helps to avoid the error where the variable name is mis-typed in the ELSE clause. | ||
== Passing an argument by value == | == Passing an argument by value == | ||
Regarding 5.7 "Variables passed to subroutines can be passed by value", scalar variables can be wrapped in parentheses to pass by value, but an array element cannot. Calling FMTPHONE((CM.REC(CM$PHONE))) will pass a pointer reference to the array element, not a copy of its value, so the array element's value may be changed by the subroutine/function. | Regarding 5.7 "Variables passed to subroutines can be passed by value", scalar variables can be wrapped in parentheses to pass by value, but an array element cannot. Calling <code>FMTPHONE((CM.REC(CM$PHONE)))</code> will pass a pointer reference to the array element, not a copy of its value, so the array element's value may be changed by the subroutine/function. | ||
A better way to ensure an argument is passed by value is to prepend or append an empty string. | A better way to ensure an argument is passed by value is to prepend or append an empty string. | ||
Line 13: | Line 19: | ||
EQU BYVAL LIT \ "": \ | EQU BYVAL LIT \ "": \ | ||
CALL FMTPHONE(BYVAL CM.REC(CM$PHONE)) | CALL FMTPHONE(BYVAL CM.REC(CM$PHONE)) | ||
This EQU BYVAL is too magical for my taste - it looks very much like a built-in language feature. The idea of passing-by-value is really good, I've had many bugs caused by not doing this. | |||
== 3.1. Generous use of whitespace makes programs easier to read, and makes blocks of code stand out. Use extra blank lines instead of *'s, which clutter up programs.== | |||
I used to agree with this when I was an IT'er who spent years at one job. Now I'm consulting, hopping from machine to machine like a gadfly, it's really handy to be able to ED BP PROGNAME and paste the entire program in quickly. Blank lines prevent that. It's a matter of taste, but there are good reasons for eschewing blanks. I changed my code formatter to enforce that: https://github.com/ianmcgowan/SCI.BP/blob/master/BFORMAT |
Latest revision as of 23:56, 18 June 2020
Using a code formatter
One general statement - it's one thing to write a document that all programmers on your system *should* follow. To make sure all these great ideas *are* followed, I'd encourage creating a formatter/linter/pre-compiler specific to your needs and embedding that in your pipeline for moving code from dev->test->prod. Not everything can be enforced, but hard and fast rules can and should be automatically applied.
Ternary assignment preferred
Regarding 2.10 "Avoid using obscure and unfamiliar coding styles", the example shows ternary assignment as "BAD"; that is, obscure and unfamiliar to most PICK programmers. I actually prefer to use ternary assignment instead of multi-line IF-THEN-ELSE logic. Ternary assignment helps to avoid the error where the variable name is mis-typed in the ELSE clause.
Passing an argument by value
Regarding 5.7 "Variables passed to subroutines can be passed by value", scalar variables can be wrapped in parentheses to pass by value, but an array element cannot. Calling FMTPHONE((CM.REC(CM$PHONE)))
will pass a pointer reference to the array element, not a copy of its value, so the array element's value may be changed by the subroutine/function.
A better way to ensure an argument is passed by value is to prepend or append an empty string.
CALL FMTPHONE("":CM.REC(CM$PHONE))
This can be made more explicit with an equate:
EQU BYVAL LIT \ "": \ CALL FMTPHONE(BYVAL CM.REC(CM$PHONE))
This EQU BYVAL is too magical for my taste - it looks very much like a built-in language feature. The idea of passing-by-value is really good, I've had many bugs caused by not doing this.
3.1. Generous use of whitespace makes programs easier to read, and makes blocks of code stand out. Use extra blank lines instead of *'s, which clutter up programs.
I used to agree with this when I was an IT'er who spent years at one job. Now I'm consulting, hopping from machine to machine like a gadfly, it's really handy to be able to ED BP PROGNAME and paste the entire program in quickly. Blank lines prevent that. It's a matter of taste, but there are good reasons for eschewing blanks. I changed my code formatter to enforce that: https://github.com/ianmcgowan/SCI.BP/blob/master/BFORMAT