My preferred entry macros use a workarea beginning with a save area, with 
standard labels for the SA part of the DSECT. They include COPY code for global 
SET symbols and a macro for parsing options out of SYSPARM. The eye catcher 
includes a timestamp.

There is spaghetti code without GOTO and there are clean programs that use 
GOTO.Branch labels still have legitimate uses.

ObThanksGregMushial I use dependent and labelled USING to avoid clutter.

I use *both* block comments and line comments; each has an important role.

Saving storage is not a valid excuse for cryptic messages.


--
Shmuel (Seymour J.) Metz
http://mason.gmu.edu/~smetz3

________________________________________
From: IBM Mainframe Discussion List [IBM-MAIN@LISTSERV.UA.EDU] on behalf of Rob 
Scott [rsc...@rocketsoftware.com]
Sent: Wednesday, June 16, 2021 11:19 AM
To: IBM-MAIN@LISTSERV.UA.EDU
Subject: Re: Coding for the future

My 2c  (assembler bias).

(1) Get yourself decent module and subroutine entry and exit macros that handle 
passing parameters and returning RC,RSN and output pointer.
(1a) Don't use any register apart from R15, R0 and R1 to return info to caller.
(1b) Too much logical nest indenting is nature's way of telling you that you 
need a new subroutine.
(1c) Always think "can what I am writing be made into a generic function and 
used by other modules?"

(2) Get yourself a decent internal trace routine - this is worth its weight in 
gold

(3) No branch labels - use structured programming macros - no spaghetti
(3a) Recovery points (and things like EODAD) are only exception to this rule, 
but are hidden from normal view under a macro specification
(3b) Single entry + single exit from any subroutine or module
(3c) FLOWASM - game changer

(4) Long and descriptive variable names with namespace of the related structure 
followed by one or more separator chars (eg "_")
(4a) Your DSA/working storage is a structure - use a standard name for it (I 
use "WA" and then "WA_FOO_BAR" etc )
(4b) Your constants (global or local) are part of a logical structure - use a 
standard name for it (I use "LC" for local constants and then "LC_FOO_BAR").
(4c) Global equates in a separate macro/copybook

(5) Strict naming standards, especially for equates and bitmasks , for example 
for structure "FOOBAR", its length equate is always "FOOBAR@LEN" and for flag 
byte "FOOBAR_STATUS_FLAG", the bitmask equates would be something like 
"FOOBAR@STATUS_FLAG_ACTIVE"
(5a) Using the above - I can code a macro that turns a bit on/off *without* 
having to know the name of the flag byte field (which eliminates a common 
hard-to-find problem where the a bit is turned on in the wrong flag byte)

(6) Always DROP and re-establish USINGs when entering subroutines - hanging 
USINGs are very dangerous
(6a) In my code this is done by module/subroutine prologue/epilog macros

(7) Use reason codes with component IDs for the CSECT where the code was set
(7a) RC = xx RSN=ccccyyyy (xx = RC, yyyy = RSN, cccc = component ID of CSECT 
that set "yyyy")
(7b) RC+RSN can be surfaced many CSECTs above where originally set - really 
helps debug/trace efforts

(8) Comment box and not lines
(8a) Line comments get out of date with the source and copied around to the 
point of confusion
(8b) Comment box above sequence of lines describes what they are doing and 
remains relevant
(8c) Long variable names and naming standards help in making each line of code 
easier to follow



-----Original Message-----
From: IBM Mainframe Discussion List <IBM-MAIN@LISTSERV.UA.EDU> On Behalf Of 
Phil Smith III
Sent: 16 June 2021 14:38
To: IBM-MAIN@LISTSERV.UA.EDU
Subject: Re: Coding for the future

EXTERNAL EMAIL





A fun thread.



Bob Bridges wrote, in part:

>1) long-winded variable names



I used to write almost exclusively in assembler, before long variable names, so 
I’ve found this one hard to break—but it’s definitely a good idea.



I tend to cluster labels as much as possible: that is, in routine Banana, I’ll 
use labels BananaStart, BananaTop, and the like. (OK, I’m pretending that I use 
long labels here—more like BANANAST, BANANATP, etc., but I’m workin’ on it.) 
This helps avoid surprises at assembly time when some other fruit gets involved 
elsewhere in the program later.



>2) comment your work...I'm more likely to use one-line comments on every other 
>line and a paragraph at the head of each section.



I learned this the hard way almost 40 years ago. Back at UofW, we ran a local 
CMS mod on VM/SP for a couple of months over the summer, when usage was light 
and we could afford the cycles. It logged the name of every command run off the 
system Y-disk. Then we would look at that data (early analytics!) and look for 
candidates to move into the nucleus (shared memory).



One afternoon I was looking at a local CP mod we had that would let an 
unprivileged user get several bits of info about another logged on user all at 
once as a set of bitflags, instead of having to issue and parse multiple 
commands. I wrote a bit of assembler to exercise it. No comments—not even 
register equates—since it was just a quick&dirty little program. Then I added a 
few bells and whistles. Then a few more…



You can guess where this is going: that module got put on the system disk 
because someone else found it useful, and the next year when we ran our 
analysis, it was the most heavily used local bit of code on the system. By this 
point it was over 2KLOC. Still no comments, no register equates. Yes, that’s 
the point when I decided I’d better change jobs :)



I have been religious about comments since then. As Charles notes, there’s a 
skill to commenting. I’ve found way too many experienced programmers who can’t 
seem to grok this, and who say “There’s no point in commenting every line, it’s 
obvious what it does”. They’re missing the point: the question isn’t WHAT it 
does, it’s WHY. That SR R2,R2 is clearing R2; we get that, and you’re right, it 
isn’t worth noting. WHY is it doing it? “Clear MVCL input length”, “Tell XYZ no 
florks are available”, are meaningful and useful.



The z/VM source code is an example of commenting done right. The ratio of code 
to comments is probably below 1.0. This is a good thing.



Gil added:

> An account of how it does

>what it does can also be useful, but that tends not to

>change when the program itself does.



I’ve seen this argument against commenting *at all*. I don’t buy it: not 
updating the comments means you’re only doing part of the job. If you change 
how it operates, you HAVE to fix the comments as part of that.



>3) Don't assume system commands will work correctly



Also theological purity, absolutely critical. I’ve long said:

            Application programmers worry about how it will work.

            System programmers worry about how it will fail.



Corollary: don’t deliberately hide errors unless you also check them. In CMS, 
an unknown command returns a negative return code. I spent several days on a 
weird customer problem back at Sterling that I eventually diagnosed as a Rexx 
program that someone had put TRACE O in for no reason. If they’d left it alone 
as TRACE N, the unknown command that “couldn’t” fail would have been traced. 
Even better, of course, would have been if the code explicitly checked for that 
failure, but this example counts as someone deliberately suppressing useful 
information. Don’t be that guy (gal).



>4) Allow arguments in any order



Indeed. Positionals with meaning of course make sense in some cases, but *ix 
always irritates me that you can’t put the ‑whatever option after unflagged 
positional arguments.



>5) Consistent indentation



Don’t get me started…! On CMS, REXXFORM XEDIT is invaluable for indenting Rexx 
consistently. Nobody has ever converted it to work in ISPF, which is a shame. 
If someone’s interested, I’ll happily help; my ISPF macro skills are not up to 
the task, I’m afraid. REXXFORM not only indents, but (unsurprisingly) finds 
many basic syntax errors in the process, so it often saves debugging time as 
well.



I’ve not done much Python programming, but the fact that indention is embedded 
in the language structure is interesting.



OK, new items:

6) When you make changes to a program, ALWAYS examine the delta by hand. This 
is easier in CMS, where you’ll use XEDIT in update mode and can thus look at 
the resulting update deck, but compare utilities and source control systems 
provide this as well. Yet I see folks not doing it in too many cases, so some 
debugging display winds up getting committed, etc. Obvious exception: complete 
refactor (when did “rewrite” become “refactor”, and why?).



7) (I expect pushback on this one)

Also learned from VM (and done to some extent in z/OS): name modules and entry 
points with a common prefix. This minimizes collisions and makes it clearer 
what’s doing what. If module ABCXYZ ABENDs, and you know that prefix ABC means 
program ABC, then you’re already ahead of the game, vs. having to figure out 
what program the FETCH module is part of. People claim that naming modules with 
“more descriptive names” is somehow magic; if they contain ONE function, maybe. 
Otherwise, the name is as likely to be confusing as helpful in my experience. 
CP contains a few thousand modules, with six-character names and 
three-character prefixes. Those three trailing characters can and do contain a 
lot of information, and the fact that HCPFRCVM is an entry point in HCPFRC 
means that when you want to look at HCPFRCVM, you don’t have to first search 
the source tree to find the code. It also means that all messages from HCPFRC 
are prefixed with that string, so, again, you know a lot before you even start. 
I cannot (and don’t care to) think about the time I’ve wasted grepping for 
function names or header file definitions in source code because people did not 
follow this simple, basic rule. Yes, it also means that DSECT or header files 
use a naming scheme, as do the entries in them: the HCPFRCBK defines the FRCBK, 
and the variables in it all start with FRC. Rigor, rigor, rigor. It saves 
lives.*



...phsiii



*You save enough time across multiple people, you’ve net saved a life.


----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions, send email to 
lists...@listserv.ua.edu with the message: INFO IBM-MAIN

================================
Rocket Software, Inc. and subsidiaries ■ 77 Fourth Avenue, Waltham MA 02451 ■ 
Main Office Toll Free Number: +1 855.577.4323
Contact Customer Support: 
https://my.rocketsoftware.com/RocketCommunity/RCEmailSupport
Unsubscribe from Marketing Messages/Manage Your Subscription Preferences - 
http://www.rocketsoftware.com/manage-your-email-preferences
Privacy Policy - http://www.rocketsoftware.com/company/legal/privacy-policy
================================

This communication and any attachments may contain confidential information of 
Rocket Software, Inc. All unauthorized use, disclosure or distribution is 
prohibited. If you are not the intended recipient, please notify Rocket 
Software immediately and destroy all copies of this communication. Thank you.

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN

Reply via email to