2009-11-30

RTFM

Although the acronym "RTFM" may be of (relatively) recent origin, the issue that prompted its creation goes back many years.

Back in the olden days when all manuals were on hard copy only, many programmers were too lazy to walk to the rack and look up the information for themselves. They would show up at my desk, demanding that I help them solve their problem.

Being young and anxious to show off my recently acquired knowledge, I would give them the answer and then try to explain the reasoning process that I went through to get there. It was at that point their eyes would start to glaze over, and I could tell they didn't want to learn anything...they just wanted to get past an obstacle so that they could finish their task.

What has changed since those days? Nowadays, with email and the Internet, you don't get to actually see their eyes glaze over.

2009-11-27

You can't do that with SQL

A long time ago I led a DB2 pilot project for one of IBM's earliest DB2 customers in Canada. By default, that made me one of the most experienced DB2 users, outside of IBM, in the country.

It wasn't long before it all went to my head, and I found myself making authoritative pronouncements on all things DB2 related. Why not? I was qualified; I had a whole 3 months of DB2 experience to draw on.

One of the challenges was learning how to use SQL when our only reference materials came from a 5 day IBM course. As you might expect, we ran into one obstacle after another. And it wasn't just SQL, we had to figure out how to Bind PLANs (there were no Packages in those days) and how to set up and use a DB2 test environment.

My programmers would ask me for advice on how to code an SQL statement and most of the time I could help them, but once in a while I had to declare: "You can't do that with SQL." I was the DB2 ghuru after all, so if I couldn't figure out how to do it, then obviously it was impossible.

Well, there was this very bright young trainee who, after hearing me say "You can't do that with SQL", came back 30 minutes later with an SQL statement that did exactly what I said couldn't be done.

I took it with good humour, not at all irritated to be corrected by a mere trainee. (Well, not for the first few times anyway). It eventually became a sort of game: every time I used the words "can't" and "SQL" in the same sentence, he would (almost) always prove me wrong.

That was an important lesson for me: whenever you think you're the smartest guy in the room, take another look, you may have missed someone.

HELP

If I had a nickel for every time I've seen a blank look after asking "Did you try the HELP key?", I could have retired years ago.

Debugging tools and oncall support

Debugging tools can require a fair amount of effort to set up, which sometimes earns them the reputation of being a waste of time. "Just put a DISPLAY message in the code, for God's sake!"says the project leader whose programming days are long behind him.

If a debugging tool is seen as a "waste of time" it is usually because the installation hasn't put enough effort into tailoring it for local use.

When we installed IBM Debug Tool in our shop, we altered all of our standard compile procs to support the TEST option and to link in the CEEUOPT module when needed. All the programmer has to do is select the TEST option on a panel and provide the VTAM LU of his debug terminal.

We never use the IBM supplied ISPF dialog to set up our debug sessions. I am not knocking IBM, but their dialog, of necessity, has to be generic, and like all generic tools requires a fair amount of effort to use. (This is where the "waste of time" perception comes into play).

We also provided each developer with a private DB2 data base for unit testing/debugging, and developed some in house tools to help them maintain them. This addresses data base contention concerns cause by people sitting at a breakpoint.

Finally, we renovated our once rarely used BTS environment to accommodate all of these changes.

It is the programmer who puts Display messages in the code that is "wasting time".

RTFC

Why do some programmers prefer to spend hours yakking about what a program might be doing, or what it ought to be doing, rather than actually reading the code? I may be old-fashioned, but I think that it is the programmer's job to RTFC. Many of them ("us", actually, since I still do a lot of programming) are too lazy, especially if the code in question was written by someone else.

I think that is why some systems programmers seek to induce fear in the hearts of application programmers. I used to think that this was merely a form of torture for the sysprog's amusement, but I believe this is actually a type of training.

The sysprog's hope is that if he consistently ridicules them for asking stupid questions, eventually the questions will get better. Maybe even to the point that the programmer will start to RTFC (and RTFM!) before asking for help. A forlorn hope perhaps.

Clockwise?

I remember when I first taught my son how to use a wrench. I had to explain to him the difference between "clockwise" and "counter-clockwise". It was not obvious to him because of digital clocks.

He must have understood the lesson because he is an engineer now.

Buffer this!

A learned colleague of mine coded a process that attempted to access the same row on a DB2 table 375 million times per run. (It was a code lookup). When I pointed this out he dismissed my advice by insisting that it didn't matter because the data would be sitting in a DB2 buffer anyway so there would be no I/O cost.

What he didn't reckon on was the CPU path length of the DB2 SELECT statement he was using. It is a long way from Cobol to DB2 and back again even when DB2 doesn't do any I/O. When we changed the process to use an in-core table, the CPU usage dropped from several hours to several minutes.

The moral is: sometimes a little knowledge is more dangerous than no knowledge at all.

Who do you believe, the programmer or the code?

When asking for advice, Programmers will tell you what they coded, but what they really mean is:

"This is what I think I coded" or "This is what I meant to code".

RTFC is the only way to be sure.

Another reason not to share your password

When I was a junior programmer I was loaned out to another project for half a day. The PL didn't want to bother setting up my RACF access for such a short assignment, so he just gave me his password (which was against the rules, even in those days) and let me use his TSO userid.

The PL had PFK10 set up as CANCEL. This screwed me up because my own userid had PFK10 set up as SAVE. After losing several rounds of changes by hitting CANCEL when I meant SAVE, I changed the PL's PFK10 setting to match the one I was accustomed to.

This would have been fine except that I forgot to change it back again when I finished using his userid.

I heard some colourful language the next day when the PL SAVE'd some changes he'd meant to CANCEL.

He couldn't very well report me to Security, since he shouldn't have let me use his userid in the first place.

Practical jokes on the 'frame

I know 'someone' who once wrote a clist that displayed an exact replica of the TSO logon screen that was in use at the time.

The clist was named after a commonly used local function, so when the poor victim used it, he would think that he'd been booted off the system. He'd scratch his head, and try to log on again, but the "logon" screen would ignore his password. It was programmed to unlock itself after about 10 attempts.

Uninitialized storage (1)

Assumptions about the state of uninitialized storage can bite the best of us. Last year we ran into a problem with the Cobol code generated by the SQL Coprocessor using Enterprise Cobol 3.3 under DB2 V8.

In the SQL---PLIST it was generating the following FILLER area:

02 SQL---STMT-NUM PIC S9(9) COMP-5.
02 FILLER PIC X(20).

Apparently the FILLER area is used by DB2 to store some bit switches and its logic assumes that initially the FILLER contains x'00'. *Usually* this is true, but we ran into some very weird application abends in a production IMS MPR.

It turned out that we were a bit behind in our Cobol maintenance. After the maintenance was applied the generated code changed to:

02 SQL---STMT-NUM PIC S9(9) COMP-5.
02 FILLER PIC X(20) VALUE IS
X'0000000000000000000000000000000000000000.

In my experience this is one of the very few times which a programmer's protest that "It's not my fault!" turned out to be true.

Masking test data

Many organizations demand that all identifying personal information be scrambled when a copy of production data is used for system testing. The idea is to limit the damage if the data is accidentally released to the outside world. Printing a test version of a client statement that accidentally gets routed to the mail room, for example.

As we found out a couple of years ago, masking can bite you in ways that you might not expect.

We were testing a new release of a recently developed system using data where the client's name was scrambled to a bunch of random characters. The testing went smoothly, and the new release went into production.

It was not until we were running in production that we realized that one of the screens was transposing the client's first name and surname on the data base. The error had gone unnoticed by the programmer and the testing / QA teams simply because the scrambled names lacked the visual cues that made the problem obvious once real names were used.

Field Name Prefix on DCLGEN command

I strongly advise using the "Field Name Prefix" feature of the DCLGEN command. This causes each Cobol field in the DCLGEN to have the same prefix. This makes coding much easier, as it can eliminate the need to code Cobol "OF"s when referring to a field.

How many of your tables contain an account number field? A good many of them, probably. It is easier to code

MOVE WS-TEMP-ACCT-NUM TO VIFCACCT-ACCT-NUM

than

MOVE WS-TEMP-ACCT-NUM TO ACCT-NUM OF ACCT-TABLE.

Using prefixes, the programmer can tell at a glance which ACCT-NUM is being referred to.

The prefix name should be related to the table name. Our shop adopted a procedure in which we establish an 8 character 'short name' for each table. The short name is used as the prefix name, and is also used to build the table space name.

I feel so strongly about this that, years ago, before DCLGEN even had a "Field Name Prefix" feature, I wrote an edit macro that added a field name prefix to the DCLGEN output. It is still in use today.

ISPF survey

Asked on ISPF-L:

Who uses the panels you develop and support?

Other programmers, mostly.

Do you continue to create new panels or is your panel library fairly static?

I create new ones on a regular basis.

Are you a private company or a government agency?

I am a self-employed consultant, currently working for a government agency.

Is there any other product you use to generate panels in ISPF?

No. I have never felt the need for one.

Do you think it wise to migrate to DTL or would that be akin to walking to the edge of mount doom with my precious?

No. I would rather put my command line at the bottom of the screen than use DTL.

2009-11-26

Advice

Here is a list of some dubious career advice that I've been given over the years. The degree of dubiousness varies.

1981 : "Stay away from COBOL...it's a dead language."

1982: "Structured analysis, structured design, structured code...everything else is crap"

1983: "There won't be any more batch processing within 5 years, everything will be online"

1984: "Find another line of work. 4GLs will make programmers obsolete."

1985: "What, you're still using VSAM? Get a database!"

1986: "Hierarchical data bases are obsolete. If you're not relational, you're not in the game!"

1987: "*Still* using COBOL? You dumb #$@!"

1988: "CASE tools will solve the application backlog"

1989: "Code reuse will solve the application backlog"

1990: "Forget CASE tools. Desktop development is much faster!"

1991: "The mainframe is dead. Go client server"

1992: "Find another line of work. Overseas outsourcing will put you out of a job"

1993: "OO analysis, design and development will solve the application backlog"

1994: "What? You're still using IMS??"

1995: "Forget Cobol. Learn C".

1996: "Forget C. Learn C++".

1997: "Y2K will be the end of the world as we know it"

1998: "Okay, maybe COBOL isn't dead....but it will be after Y2K is finished"

1999: "All future application development will be in JAVA"

2000: "The mainframe is the best platform for e-business"

2001-present: I stopped listening to advice. :-)

The jury is still out on some of these items.....

2009-11-17

Whose default is it? (sorry)

The LE run time parameter CBLQDA can bite the unwary.  It doesn't help that IBM has changed the default value over the years.  I was just recently able to convince our local sysprogs to change it to OFF.  Their first reaction was that there had been no change, that the system had always behaved that way, and OFF was the default. 

The story I heard was that IBM originally delivered CBLQDA(ON) as the default, with a recommendation to turn it OFF.  This was to comply with some ANSI COBOL standard.  Our local sysprogs accepted IBM's recommendation and set it to OFF.  A few years later, IBM changed the default to 'OFF'.  The local sysprogs knew that in the past they didn't use the default value, so, by reflex, they switched it to 'ON'.  And for a long time no one complained.

(For those not intimately familiar with IBM's Language Environment, the CBLQDA setting controls the behaviour of COBOL programs that fail to assign a dd name to an output file.  CBLQDA(OFF) means that an error is thrown, CBLQDA(ON) means that the problem is ignored.)

I was remined of this when I was approached by a desperate colleague who had been banging his head against the wall for two days, trying to figure out why, no matter what he did, his output file remained empty.  He could see the EXCP counts, so he knew data was being written somewhere.  It turned out he had a misspelled ddname, and because CBLQDA(ON) was in effect, z/OS was writing to output to an uncataloged temporary file instead of the one that was intended.

Ouch.

2009-11-14

Standards are forever

I am presently working at a shop where static linked modules are the standard practice. Much to my dismay, convincing them to change to DYNAM is proving to be more difficult than I expected.  Change is a constant in this business, except where Standards are concerned.

Fortunately, the chief defender of the standard retired recently, so there is now some hope that it will change.

2009-11-06

Oops!

So what is a mere developer to do when he catches his DBA or sysprog in an error?
  1. Mercilessly mock him. It's payback time baby! Or,
  2. Tell the sysprog that it is all your fault, that you should have known the answer yourself. Apologize for wasting his time. Or,
  3. Express your astonishment that the laws of physics were changed in the last release, and there is no way on earth that anyone could have known the answer. Or,
  4. Take him out for a beer. With any luck, he'll offer to pay for it. This time. The other 99% of the time the beer is on you.
Do I need to tell you what the best option is?

Disclaimer: this post is an attempt at humour. Some of my best friends are DBAs and systems programmers.

SDLC: system testing

You won't find these in any methodology textbook. Here are the 10 stages of system testing:

  1. Unwarranted optimism: "Everything will be fine....it says so in the Plan"
  2. Denial: "It must have worked...look at the results again"
  3. Bewilderment: "What do you mean, it didn't work?"
  4. Confusion: "That didn't work either!?"
  5. Panic: "Nothing is working!!!"
  6. Despair: "We're doomed...nothing will ever work"
  7. Desperation: "Maybe if we call it an 'original bug' no one will blame us!"
  8. Bargaining: "Maybe if we defer some more requirements to phase 2 we can get this phase finished"
  9. Hope: "It's working now?"
  10. Smugness: "I told you it would work. Just like we Planned it."
What stage is your project in?

SDLC: Production support

Ah, the forgotten phase of every project. Production Support never gets the respect that it deserves. It too goes though phases:
  1. Disbelief: "But it worked during UAT!"
  2. Denial: "It must be an implementation problem...not our fault"
  3. Dodging: "Prod support can deal with it". And now the Prod support team takes a look at it...
  4. Anger: "Those idiots on the project team couldn't have tested this"
  5. Confusion: "What the hell is this anyway?"
  6. Dismay: "Oh crap....there's no way that we can fix this"
  7. Bargaining: "Wait a minute...isn't it still under Warranty?"
  8. Glee: "It's screwed up, and it's not *our* fault!" Now it is sent back to the Project team....
  9. Disgust: "Those idiots in Prod support couldn't find their butts with both hands"
  10. ...there is no end to this list

And the survey says.....

Questions originally posted on comp.lang.cobol by Pete Dashwood. Answers are mine.

1. What is your personal attitude to your management? Do you see them as a bunch of wankers who have no idea what's going on or is required, no understanding of the problems you have to grapple with every day, and just an unnecessary departmental overhead because a trained monkey could do their job?

As a species Managers are wonderful. They give direction and comfort to those who need it the most.

2. Do you have any aspirations to ever be management? Why? Why not?

It is something that I aspire to. With the right mentor it might be possible.

3. Could your attitude affect your management? (d'you think...?)

Definitely. It is important to try to see the big picture...when you look at things that way your manager is always right.

4. Would you do exactly what is specified in say, a program spec., even if you knew it was wrong, and would cause major disruption to downstream processing? How would you deal with this situation (if at all)?

My manager has an open mind as well as an open door. He would listen to my concerns, and then share his wisdom with me. I would soon realize that I am mistaken and he is correct.

5. In meetings, do you speak your mind and to Hell with them if they don't like it, or do you tend to pussyfoot for the sake of annual review? Would you modify your language depending on the level of management present? Why? Why not?

Managers are always open to honest feedback. I see no reason why they would be offended by such.

6. Are you gleeful when your manager is in trouble?

Not at all. I fret over it, and do whatever I can to help him overcome it.

7. Does your manager socialise with you on occasion? Is it comfortable or would you rather they didn't?

I am not worthy.

8. If you screwed up, would you look for support from your manager or would you make every effort to hide your blunder or divert attention from it until you could fix it, if you could fix it?

I would admit my guilt immediately and work whatever overtime was necessary to correct my error.

In conclusion, my manager is a wise and powerful leader. And he monitors my blog postings.

Mythbusting: DB2 results table

DB2 does not always create a results table. This is a common misunderstanding because programmers are taught to code their cursors as if the results have already been materialized.

We had a case in our shop, shortly after migrating to DB2 V8, of recently inserted rows suddenly appearing within a cursor. The programmer was indignant, insisting that since the program hadn't been changed, this must be a DB2 V8 issue. Well, DB2 has never guaranteed that this would not happen in an ambiguous cursor. It was therefore not a bug in DB2 V8, we'd just been lucky for the previous several years.

More recent versions of DB2 allow much more control over this situation than in the past.

Adding INSENSITIVE SCROLL solved the problem for us. It was an easier alternative than changing the application to ignore recently (within the same unit of work) inserted rows.

Even a very experienced and expert programmer (ahem) can trip over this one. I once changed an online program to insert rows into the same table that was the subject of a cursor. The rows were inserted after the current row, so the FETCH loop just kept running, endlessly chasing EOF without ever getting there. Doh!

Fortunately, the problem was caught during unit testing.

Using I/O subroutines to access DB2 tables

DB2 shops have been debating this one for years.

One problem with using subroutines for all I/O is that you lose DB2's ability to fetch just the column(s) you are interested in. I/O subroutines are usually pretty generic, essentially doing a SELECT * on the requested table. *

Performance geeks will complain about the CPU cost of fetching more columns than you really need. DBAs will complain that you are using DB2 as if it was IMS. And your data modelers, well, they'll just complain, as they always do, that you didn't implement their model properly.

The only one who won't complain will be your project manager, because the I/O routines save you coding time. (Assuming that the poor sap coding the I/O routine isn't working for him too.)

* I once saw an application where an attempt was made to mitigate this problem by requiring the calling program to pass an array of flags, each one corresponding to a column that was to be retrieved. As you can imagine, this bloated the code (no dynamic SQL allowed!) in the I/O subroutine to the point that the cure was worse than the disease.

So you want to do a 7 table join?

My usual advice when faced with a query like this is to break it up into simpler parts. Just because you can do something with a single query, doesn't mean that you should. Temporary tables (or QMF's SAVE DATA) are an excellent way to achieve this.

Why FTP?

I have never understood the fascination with FTP. If all you want to do is transfer files between z/OS and a Windows workstation, then ISPF's Work Station Agent (WSA) works great. It's simple to use, fast and secure. Best of all, you can automate it using Rexx or any other language that supports ISPF dialog services.

See this link if you want to learn more about WSA.

Still not convinced? See this one too.

Cobol scope terminators

All the scope terminators are great, but I especially like END-IF because it allows you to avoid programming in SENTENCES. IMO, the designers of Cobol took the natural language metaphor a bit too far when they introduced the concept of logic flow delimited by periods (aka "full stops").

IMO the lack of END-IF in early versions of Cobol severely damaged the reputation of the language. I think that is the reason why Dijsktra said:

"The use of COBOL cripples the mind; its teaching should, therefore, be regarded as a criminal offense.”

END-IF is easily the most important innovation ever made to the language in the 28 years that I've been working with it.

Some of my best friends are DBAs

Don't judge DBA's too harshly. They're not programmers, and may never have actually coded a cursor themselves.

IPT vs ISPF

I find this link interesting because IBM appears to be rubbishing ISPF in order to promote IPT

ftp://ftp.software.ibm.com/software/...Comparison.pdf

Straw men walking! 

Feeling young

Hearing old timers talk about TSO edit makes me feel young. (A rare pleasure that is getting rarer).

I was one of the first generation of programmers to have the privilege of using SPF right at the start of my career. During my entry level training, the topic of TSO was glossed over; I never even had to learn TSO Edit.

This was back in 1981, when it was called SPF (Structured Programming Facility). A few years later it was re-branded as ISPF (Interactive Structured Programming Facility...."Interactive" being the buzzword of the day).

Then, sometime in the late 1980s ISPF became "Integrated Systems Productivity Facility". "Integrated" was a fashionable buzzword at the time, and IBM decided that ISPF wasn't just for "Programming" any more.

Nowadays the official name of the product is "Interactive System Productivity Facility". Whatever happened to "Integrated"? Perhaps I have my chronology wrong.

Your memories may vary.  (Mine vary from day to day).

I think I first saw option 3.4 in 1986 +- 1 year or so. I didn't like it very much...real programmers knew all of their data set names, so who needs 3.4? (Twenty years later, I am hooked on SimpList, a product which is like 3.4 on steroids).

I remember when you had to hit RETURN rather than ENTER in order to use a Jump function. I also remember complaining when they changed that, but I soon got used to it.

How long should a process take?

"How long is a piece of string?" may be the flippant answer, but it's not a very useful one.

It is possible to predict, with a fair amount of accuracy, how long a process will take if you know how many records must be processed, what is being done to them, what type of machine it is running on, how many i/o buffers are available etc etc

Or, you can run the input file through DFSORT or other high performance utility.

If DFSORT can process a file in 10 minutes (even if it's not doing exactly the same processing...most business applications are I/O bound) and my Cobol program can do it in 15, then I don't spend much time tuning the Cobol because it is probably about as good as it is going to get.

That is just a rule of thumb of course. Your mileage will vary.