“Subfiles in RPGIV” and Me

May 2nd, 2009

Subfile processing is an integral part of RPGIV data entry and data display. To be a real pro, you need to handle them properly. There are any number of ways to build and maintain them. Depending upon your level of expertise, you can do really sophisticated data processing tasks with subfiles. (Yes, I know that phrase data processing is so 1970’s.)

Dealing with them at my place of employment is an ongoing task. My two fellow programmers, though having much experience in programming, are relatively new to RPGIV. To help enhance their skills, one of them bought the excellent book by Kevin Vandever, “Subfiles in RPGIV”.

One of them was using it to help him build the first subfile program he had ever written from scratch. And wouldn’t you know, his techniques were different from mine! And the author had used my technique when he first started programming subfiles, but he had found a better one. Oh, my.

For the uninitiated, subfiles are a way to handle update and display of data files, by allowing you to display multiple instances of data in (usually) a columnar format, then treat each line as a separate data record. In RPGII, subfiles were not available; to process it, you had to plug your file data into arrays of information, each data field in an individual record linked by being the same array element in multiple arrays.

Anyway, the author recommends a technique that is clean and efficient. He uses the DDS keyword SFLNXTCHG to allow the programmer to flag for further processing data in a record that has been changed. The operating system keeps track of changes, and this allows the programmer to process only those subfile records that have been changed by the programmer. This is done by using the READC (Read Changed record) RPG opcode. Using SFLNXTCHG with an indicator allows the programmer to mark a line of data as “changed” when it processes the second time around. If one entered erroneous data in error, and the program would not accept it, the data would still be marked as “changed” and the record would be read the next time around by the READC opcode, even if the data entry person did not correct or change the data.

My approach, the way Mr. Vandever set aside, is to keep track of the number of records (entries) in the subfile. To process the subfile, I CHAIN to each subfile record by relative record number, whether it is changed or not, and process the data as needed. I can do this as many times as desired.

Why do I do it my way? Because I’m an ignorant so-and-so, I guess- or at least I was when I was learning many years ago how to program subfiles. I vaguely remember attempting to use READC to process only changed subfile records. However, I was not aware of the SFLNXTCHG keyword; and when I would read a subfile record and find an error, I couldn’t see how to tell the system to process the record the next time around. Suppose the screen had five subfile records displayed. I changed two records, and one of them was in error. Once I fixed the one in error and the program looped through with the READC opcode again, it would not pick up the correct one from the previous pass because it couldn’t tell it has been changed! When I saw an example of the CHAIN technique, I realized that it would always work, so I stuck with that technique.

So do I change now to the more efficient technique in the future? Wellll…. probably not. Being a creature of habit, for one thing; and the fact that changing my technique will not gain me all that much and would make the “read subfile” task more complex.

But what about all the unnecessary CHAIN operations, which on a large subfile mean an awful lot more subfile accesses than necessary? If you have read my blog from the start, you might remember when I told about a hissy fit  I had when I worked on a program where a previous programmer read a detail data file by CHAIN instead of READ and increased the processing time by a factor of 10 – from 15 minutes to 2.5 hours.

I suppose that I have been corrupted by the greased lightning bottled in the latest machines. In my file cross-reference program, I load source files into subfiles so that you can drill down into the subfile and find out file characteristics, even view the data in the file by putting the cursor on a file name and clicking a function key. When I tell the system to display source, it can put 9,999 lines of source to the subfile in less than a second. Why sweat the difference in processing one record with READC versus, say, 12 when using CHAIN? In a large installation with hundreds of users on a slower machine, perhaps it would be a concern- but not now. My concerns about performance are pragmatic, not ideological. As I have said before (as a matter of fact, in that previous blog post I mentioned above), I don’t sweat over nanoseconds.

Also, at least with reference to my cross-reference program, using READC is irrelevant. I do not change the subfiles in any way. They are simply a jumping-off point for further processing. I use EXFMT (which means write the format, then accept input) to display them, but only to allow the input of a right-click or a command key or a search argument to use with a command key.

A minor quibble would also be that an edit that relied on READC would catch only errors that had been introduced by the current data entry operator. There is no way to guarantee that the data in the subfile is error-free when it is first displayed, especially if the data is also updated by other programs. If you edit every line, you can check for errors in all the data, including preexisting errors.

So my partners are free to use the new techniques, but I am not likely to choose to do so in the future.

Why Learn to Program - Can You?

April 20th, 2009

I finally found the article I read back in the 80’s about “Why You Should Learn to Program“, by Chris Crawford, an Atari game developer at the time. Evidently he had spoken on the subject somewhere; afterwards, he put his notes essentially into article form; he then felt it necessary to flesh it out with additional material.

At first glance, though, this seems to clash with the message of Peter Norvig, who either works at or has worked at Google, in his article (which I also find authoritative and based on good research) ” Teach Yourself Programming in Ten Years “. These two articles present somewhat contrasting views of the craft of programming; but I find them complementary.

Mr. Norvig’s view is the kind of view that I would expect of professional programmers. He believes that programming that not something that you can learn from a “Learn Language X in 21 Days” kind of approach. In fact, he even mused that 10,000 hours would possibly be a better view of the matter than ten years.

However, in giving his recipe for learning to program, his recipe, which obviously will involve hard work, mentions a very important first step: ”  Get interested in programming, and do some because it is fun. Make sure that it keeps being enough fun so that you will be willing to put in ten years.”

He obviously believes it should be fun. And so it should. Even if it comes relatively easily, it will almost certainly bring one a degree of frustration, if for no other reason than that you must, for any nontrivial task, explain what you want to the computer in excruciating detail.

Which brings us to Mr. Crawford’s thesis, consisting of three main ideas on why each of us should learn to program:

1. Recreation.

2. To learn the importance of clear communications.

3. “Learning to program will make you a better thinker.”

I leave you to read the article to get the details of his argument.

Where Mr. Crawford and Mr. Norvig differ are in the goals. Mr. Norvig’s recipe is for a master programmer, who could and would be paid well for mastering his craft- even if he still is doing it for fun. Spending 10,000 hours learning to program is serious stuff.

Mr. Crawford, in contrast, recognizes that there are professional programmers who will be paid well for their work; however, you don’t have to be good enough to write programs for money, to write programs. He gives the illustration of the man who takes pictures of the Golden Gate Bridge and his family while on vacation. A professional photographer would likely take a technically “better” picture and put it on a postcard for the man to buy; but he prefers his picture, because he did it himself. A person need not be a master finish carpenter to enjoy doing his own woodwork. As Crawford says, programming is not nuclear physics; anyone can do it.

He recommended BASIC in his article; even he now backs away in this respect from his 1985 recommendation. The Wirthian languages (Pascal, Modula-2, Oberon) might be better choices. There are free Pascal compilers around; if a visual environment is more your speed, try Delphi; you may be able to find earlier versions for free. You can even try Visual Basic, if that suits you. Both BASIC and Pascal were originally designed as teaching languages; if programming interests you, try one of them. (Look for them; Google is your friend.)

The main thing is, the sooner you can get payback for your learning efforts, the better. For me, RPG allowed quick output, quick results at the start. That made up for the times of frustration that could and would come later.

I highly encourage you to read these articles, which give you a good perspective of the entire programming experience. Mr. Crawford, in particular, may just incite you to find out how pleasurable the ability to program can be.

Take It Personally

March 30th, 2009

Who is responsible for creating software that works? Where should the responsibility lie?
In large software corporations, programmers will occasionally lose sight of this. A Microsoft e-mail involving Bill Gates and Moviemaker is instructive here.
This kind of situation, of course, is probably not unique to Microsoft. But still, who should be the one in charge of software quality? In this case, someone a lot lower in the hierarchy than Bill should have caught the errors and corrected the problems. And I don’t mean the project leaders, either.
I submit that each and every programmer is responsible for software quality, and he or she should be aware that the software he writes should never just be “good enough”. The software he writes should work as it is expected to work, and certainly not crash when it is being used as it is supposed to be used. This is not to say that your software will be bug-free; that may not be possible to guarantee. The next bug in your program (and obviously, we are dealing with non-trivial programs here) probably just hasn’t been found yet. But programs should not crash and burn under the most simplistic of test conditions. (I’ll never forget the time I double-clicked on the WordPerfect icon on my Windows 3.1 desktop and got an “Illegal operation” error.)
Recently, I was making some revisions to my file/program cross-reference programs. It was a substantial change striking to the source of the data I used in my program. When this was done, whole chunks of my program were commented out, to be removed later entirely once the new code was tested. Errors started popping up all over the place. (Never forget that a “bug” is not some creepy-crawly that got caught in your code; it is an ERROR.) I was actually trying to get work done that more directly relates to my job- which is not to create utility programs. I was trying to get a project done with my utility as an aid, and if it wasn’t crashing the programs, it certainly wasn’t acting as it should.
But I was taking it personally; if I write a program, it is supposed to work as designed. My program may not do everything it might ultimately be able to do; but what it does, it should do right. If I right-click on a program name, it should bring up the source for it- look in the right place for it- not tell me it can’t find it or bring up the wrong one. When I click on a file name in a program and hit the appropriate function key, it should show me the file and field description or even the data; it must not lie to me and say the file is not there, and it certainly should not crash because I performed some subfile operation wrong.
What should be the first line of defense against errors, then? It should be the individual programmer. He should consider errors unacceptable. Bugs should not become “features”. He should be willing to beat on his code, test it by as many avenues as possible. Often it is best to forget you are the programmer and just USE the software as the individual user would. If you test it in “programmer” mode, you may tend to not test it in situations where the logic is more complicated and likely to fail; to save face with yourself, you might test it in “safe” areas under ideal conditions rather than push it to its limits.
Consider it a matter of pride. Beat on the program yourself. If errors are to be found, you be the one to find them, not the user. Consider it a matter of dishonor when a user finds an error. You may not be able to prevent users entirely from finding errors; but don’t let their finding errors be the accepted mode of software quality. Whether the tester be the user or some testing team, make their work as light as possible.
Don’t let “Bill Gates” find your errors. You find them.
Take it personally.

Programming and Thinking

March 8th, 2009

I have read on more than a few occasions that it is important what programming language that you choose to write programs in, because it has a bearing on how you think about programming problems. An RPG programmer will likely approach a report program with an entirely different view than a C programmer. In this case, the RPG programmer would likely be able to take a more direct approach to the program than the C programmer, who would likely need to pay more attention to how to express the precise report layout. On the other hand, while compilers are written in C, I shudder to think of what a compiler written in RPG might look like. And can you imagine an RPG compiler written in RPG? Niklaus Wirth’s Oberon compiler was written in Oberon. Don’t ask me how.

This subject came to mind as I contemplated some of the indicator-laden code written for our system over the past 35 or so years- some original code, some heavily modified and added to over the years.

The code, of course, is hard to follow. It may have been easier to write. It’s easy to write code conditioned on one or two indicators; then a condition or two must be tested for, and all of a sudden you are slowly spun into a swirling maelstrom of competing indicators, repeating your original two as you go down the page and see how many permutations of the other three can be devised, how many of each permutation are used before the combination changes, with an occasional sixth or seventh indicator thrown in for good measure. And of course the output is conditioned on each of those permutations, with individual fields based on further combinations of those and others outside that group.

As I said, some of that code was written in the 70’s, before structured concepts began to be widely used, and certainly before they were applied to RPG. I learned how to do this even before concepts like IF-THEN-ELSE-END were even part of RPG. (See my 5/10/08 post “The Good(Indicators Part 2)”.) Evidently, not too many people read the same magazine articles I did, and even fewer implemented the concepts before IBM began to implement them in RPGIII for the System/38.

What is sad is that even after the concepts were made available, they were not well implemented in our shop. Maintenance of the old code was hard enough, but the more they modified the programs in the style they were written-whether RPGII or RPGIII- the harder they became to follow. And when RPGIV came out in the mid-90s, it was effectively ignored. I think I wrote the first RPGIV programs on our system in 2007.

When you are unwilling to implement new programming ideas, it makes the maintenance task even harder. If, when RPGIV came out, they had begun tweaking the code to make it easier to read, it would be easier to follow now; and sometimes relatively trivial tasks would not be attempted simply because the techniques that made them simple were ignored. By maintaining the old mindset, a lot of time that could have been used progressively was wasted.

A big example of this comes in the area of string handling and editing of numeric data. Of course, the handling of string data on a character-by-character basis has to be done in RPGII, RPGIII, and RPG400 by pushing them into arrays and manipulating them as individual array elements. Formatting of numeric values into, say, dollars and cents, must be done by means of edit codes and edit words, which are character patterns that define the look of a number.

An example: On a line of a subfile of a transaction history, the two numbers to be displayed could be dollar amounts (12345.67) or interest rates (123.4567). In generating the subfile, I found that you could not format the numbers in one of two different ways(using edit words), depending on whether it was to be dollars and cents or a percentage rate. This was unacceptable to the the screen format compiler; you had to pick one or the other, and the dollars and cents version was selected. This, of course, then has to be translated mentally by those who use the screen.

The solution, then, would be to output a value that could be expressed in two different ways. What I did a few years ago, before RPGIV was available, was to write the value to a temporary file (just as I would to a print file), then chain to that file and pull out the newly formatted value for use. To format a date, I would write a date as ‘03/08/09′ to a file, then access that 8-character string. Somewhat of a kludge, but it would work. There are no doubt other ways to do this in RPGII or RPGIII, but they are still likely to be kludges.

But in RPGIV, it becomes a piece of cake: Suppose you have a 7 digit numeric field NBR. You can then define a 10-character field FIELD and two edit words as constants: DOLLARS ‘ , 0. ‘ and PCT ‘ 0. ‘. You then say

IF (dollar value) EVAL FIELD=%editw(NBR:DOLLARS)

ELSE

EVAL FIELD=%EDITW(NBR:PCT)

ENDIF

This FIELD is the value that then goes into the subfile. It was very easy to test, implement, and put into production. The users were very pleased.

Now, this solution that took me only a very short time could have been done a long time ago, but it wasn’t. The possible solutions, based on the way of thinking engendered by the old programming language (RPGII) made a simple correction a daunting task, and evidently it was felt it would take too long to implement.

Now, this was not intended necessarily to be self-congratulating. It was meant to show that not being willing to learn new and better things can have longlasting consequences. More to the point, being too deeply immersed in a certain programming linguistic style can cause one to avoid ideas that could be better both for you and for your users. In an environment like this, it may not be practical to choose between C and RPG; but while choosing new stuff (change) may not always be better, it CAN be.

I Need Some Motivation….

February 14th, 2009

My previous ruminations on my attempts to learn Oberon-2 has made me think about what motivates people to program, given the native intelligence to do so.

My cohort at my place of employment provides an interesting contrast to me. He has a lot of energy and a very active mind. He started out on computers as an operator in the ’70s running the IBM machine (a System/3, I believe) at the very place we are now. Interestingly,  I found at the same time he had bought a SOL microcomputer as a kit, which he then proceded to assemble. This was while he was yet a teenager. He then learned to program it. He went on to get engineering degrees, continuing to program in whatever programming language was necessary to run the machine he was working on- not necessarily a computer per se, even. He has tweaked a text editor to do some very sophisticated things.

Obviously, he gets a charge out of making the machine that he is working on work. He was doing it before I had ever seen a real computer in person, even though he’s younger than me. I think he is the sort of person who would program even if he wasn’t being paid to do it. The more complicated the task, the better; but he seems to be drawn more to seeing what the system can do more than to any particular mundane, normal business application.

On the other hand, for me computers are an annoyance; they sometimes get in the way of computing- that is, the solving of problems. I have no patience when a computer goes belly-up in the middle of something I’m trying to accomplish. I learned programming when I was 30, past the age of youthful exuberance and loaded with family responsibilities. I would have been in trouble if the programming language available as the way I could support my family had not been RPG, or perhaps COBOL or BASIC.

My orientation has never been on the technical side of things. A simple set of instructions for assembling a bookcase throws me for a loop. Once I was trying to install a set of windshield wipers. There were no words in the instructions, only a series of diagrams. It took me about 15 or 20 minutes to figure out the instructions. My expertise is in logic. I learned to read at an early age, and I can see patterns of ideas very quickly. I can see solutions to problems very quickly; but I have a very narrow focus; sometimes this results in my missing the “forest” (solution) because of looking too closely at the path between the “trees” (the details). I can be very original in finding solutions, as long as the goal is clearly defined, preferably by someone else. I do better building on other people’s ideas than originating my own.

So I get no pleasure from the gory details of computing. The C programming language annoys me because it seems like you jump through hoops to do what you want to do. “Print” becomes an exercise in control characters; in BASIC, “PRINT” is just that, print. And C has loose ends; I don’t like a language with loose ends. C is too close to the metal- or the silicon, if you will.

So I like a programming language with clarity. C may be clear to some people; it is not to me. The same goes for C++, Java, and any number of other languages you could name. I like order; perhaps that’s why I tend to gravitate toward the Wirthian languages- Pascal, Modula, Oberon. I want a language that will help protect me from mistakes by making at least the gross mistakes illegal. I feel uncomfortable with a language that allows you make a variable numeric at one point and alphanumeric at another point in the same program, as some scripting languages do. I am not adventurous in that respect.

So when it comes to screen displays, I prefer to have the system do the work. That is not a hard and fast rule; I once built an AS/400-style data entry screen using GWBASIC because I thought line-by-line BASIC data entry was so gauche. But in general I prefer to program and let the system take care of the screens.

But sometimes I wonder. I do also like system- level things, like writing my own program-file cross reference program. I would get geeked when my partner would suggest various functions for my program, like being able to click on a file name in a program source and actually look at the data in the file or the file’s descriptions or what fields are in the file. I wanted to make my AS/400 do some things his PC could do.

So different people are motivated by different things. My partner enjoys the process. I do too. Sometimes, I guess,  it’s better not to worry about “why” and just appreciate the pleasure.

Oberon-2 Episode 2

February 12th, 2009

One thing that has cooled somewhat my desire to learn Oberon-2 is the fact that I still want to program for Windows-styled environments. Command lines and line-by-line data entry just doesn’t cut it. To do that, I will need to go to Blackbox, a programming environment that allows you to generate programs with a Windows feel (or Gnome/KDE, if you are a Windows hater).

To that end, I wanted to find a quality way to produce such a program. I was already aware that there are a number of GUI environments available for Python, so I decided to give Python another try. The GUI package I selected, after some research, was WxPython. I downloaded Python, WxPython, even Eclipse for a good editor and Python compatibility.

After I downloaded these things, though, I became aware of one thing I should have thought of before, something I was aware of even from my IBM midrange experience.

From the very beginning, Screen Design Aid (SDA) was part of the programming experience. DDS was the language used to generate the midrange screen displays, and SDA was what you used to generate the appropriate DDS specifications, which were (and are) compiled. If you wanted a heading on your screen, you typed it where you wanted it. If you wanted a field on the screen, you prefixed a set of special characters with a + in front. For example, putting a +6666666 on the screen indicated a 7-character numeric field; +BBBB, a 4-character alphanumeric input-output field; +99999999, an 8-digit input-output numeric field. When you pressed enter, the + disappeared and the field remained. Since you would no doubt want to give the field a name so you could use it when interacting with the program the screen was associated with, you would put a ? in front of the field and press enter and a prompt screen would pop up and allow you to give the field a name and even change its length if desired. To change other field characteristics, you would put an * in front of the field; this would pop up a series of prompts that would allow you to specify such characteristics as high-intensity, blink, reverse-image (from white on black to black on white), and so on. When done, you ended SDA and it would generate DDS specifications, which you then compile as a “file” for use by your RPG program.

Now, Visual Basic it wasn’t; but it protected you from having to key in those DDS specifications line by line. You did not have to get a deep understanding of DDS to produce acceptable screen output. Of course, once you got a good understanding of DDS, you could often make changes directly to ths DDS faster than you could do it by opening up SDA; the point is, you didn’t have to.

With this in mind, you may imagine how disillusioned I was when I opened up the tutorial, and what did I see in the first lesson for WxPython? Being able to size and resize radio buttons, list boxes and pushbuttons and text boxes? No. Source code. To get a box, you type in code. To get a window, you type in code. To get any widget, you type in code, with lots of lovely parameters to enhance your programming experience.

This was not enthralling. I found that WxPython doesn’t act like Visual Basic; neither does V(isual) Python, for that matter. For every little widget, you have to grind out parameter-laden code. The result, judging from the illustrations, is very nice, but it don’t come easy. (Note: There is apparently a plugin for .NET called IronPython that allows Python to be used in the .NET environment; but I’m not sure of the details about it, particularly whether or not it is free. )

Now, whether it’s RPG, Python, or Visual Basic, there is still code to write; but it is not screen code. In fact, you have to work hard to even find the actual source code generated by VB. You are shielded from the details, even as you are (or can be) using SDA in association with the RPG program.

So I will likely shy away from learning Python and WxPython. So what will I do? An experienced Oberon-2 programmer recommended I try the POW! Oberon development environment before I tried Blackbox; but even with POW!, I will still not have the GUI widgets to work with. Since I already have a good feel, I believe, for the semantics of Oberon-2 based upon my study up to now, I may just dive into BlackBox. I am an experienced programmer, so I don’t see that I’ll need to start at “Hello World”.

The Programming Group

February 1st, 2009

In considering the craft of programming, sometimes not enough attention is paid to the people you program with. Of course, if you program alone, this is not an issue, but it raises the issue of who is going to keep you in line.

To give a quick example: During the last couple of days, I wrote a little Visual Basic program to facilitate access to an organized group of mp3 files- more specifically, oral readings of Bible books. To make the routine somewhat generic, I put the location of the data in a record of a data file, and the next record in the file was of the location of the program used to read the data- in this case, Media Player. I would then use these pieces of information to build the command VB would use to play the mp3 files. It worked on my computer just fine, and I copied those locations and reentered them in a data file on the system the program was intended for. It didn’t work. But why?

I came back home to my computer and puzzled over it awhile. I then decided to go lay on the living room couch to relax. About ten minutes later, I bounced off the couch. “You idiot!” I said to myself. I realized that the drive location I specified was G:\Bible. This was fine for my home computer, but my destination computer only had a drive C. I went back and corrected it, and all was well.

This illustrates the value of being able to work with others. I didn’t discover the solution until I had disconnected my mind from the problem. In effect, I had created a new, objective observer to critique my code and the situation. The problem might have been easier to solve if I had had another pair of eyes to look at it, instead of having to clone a mental image of myself for the purpose.

Thinking of that reminds me of a situation of my earlier career (not sure if I already blogged about this or not). I had a problem with a piece of code. I sweated over it for hours. I finally decided to share it with my co-worker, a more experienced programmer. I started to describe my program as I spoke to him: “First I want to do this…..(Description) And then it’s supposed to do this….. (More description) And then I do this… And….Ohhhhhh Boyyyyyyy.” The solution to the problem leaped out at me, and my partner never had to say a word.

I am normally not a fan of having two programmers work together closely while coding, but sometimes having one or two people around to bounce around ideas can help. Once a group gets above three or four, the benefits of having a group seem to waste away. Too much clutter. If you can get a few very good programmers together, I think you can write almost anything. If you get a lot of programmers together, they seem to get in the way of each other. Doubling the number of programmers does not get double the work done. Of course, much better programmers than I discovered that fact a long time ago.

I think I like the group I am in better than any other group I have ever worked with. The oldest one in terms of experience is about my age, but he started when he came out of college, I believe. I think his first language was Algol. (I’m serious.) He has also worked the longest with my current employer, and he has the deepest understanding of the current system. The other programmer is a bit younger than me, but he worked for this employer when he was young as a computer operator, left for about 25 years, then came back to program RPG. Both of them have degrees, one of them with a Master’s in engineering, I believe. (Not sure what kind of engineering.)

Their styles are quite different. The older one is quite methodical, and he navigates the AS/400 with lightning-fast use of the menus. The younger one loves the AS/400, but he is definitely a PC guy. He has enhanced a PC programmer’s editor until he can cut, slice, and dice any data or program from the AS/400 he wants to, any way he wants to. He’s comfortable with Java and Rexx too, which makes his choice of programming options that much greater. I thought I had a quick mind until I met him; now I know I’m hopelessly slow. He is not afraid to make mistakes-if he makes a mistake, he fixes it -  while fear of making mistakes is my biggest fear. The only claim I have to superiority over them is my greater experience with RPGIV - but as fast as they can learn, that advantage will not last indefinitely.

And the best part is, we value each others’ abilities. Blend all this with management that points us in the right direction without being intrusive and lets us brainstorm and try fresh uses of our programming resources, and it would be hard to find a better programming group or programming environment.

Oberon-2 - Episode 1

January 20th, 2009

I am still trying to push myself into actually learning to put the programming language Oberon-2 into practice in an actual project. And I’m still dancing around the periphery of my programming course.

Much of the early portion of the book “Oberon-2 Programming With Windows” concerns itself with actually setting up and getting acquainted with the programming environment. An interesting aspect of this environment is that it is not exactly like the environment Niklaus Wirth created when he created the Oberon language to enable the creation of the Oberon operating system back in the 1980s. The original Oberon system did not require that modules be linked explicitly to a program. They are somewhat independent entities. How this can be so is beyond the scope of this post; but in this implementation of Oberon for Windows named Pow!, one module has to be designated as the main module, which then can be explicitly linked to other modules.

The idea of modules being integrated into a whole is hardly unique to Oberon, of course. The idea of “top-down” design goes back at least to the 1970s, where it was felt that the best way to handle complicated tasks is by breaking them down into less complicated tasks, which could also be further broken down into simpler tasks of simple resolution.

For a general purpose language, this is truly an elegant concept.

Perhaps this is where we see the main difference between elegant block structured languages and the old business languages like Cobol and RPG. I will speak of RPG, since that is what I am most familiar with. RPG IV is what might be considered a “large” language. Everything you might ever want to do in business programming is part of RPG; and when you read discussions of how RPG might be improved, you will read suggestions of features that should be ADDED to the language. You will never hear talk of modules or “libraries” or even “service programs” being able to be referenced by the language. New features must be PART of the language; and if they are implemented, they simply make the language bigger and, in most cases, more complicated.

And so we see this world-view even in the structure of RPG programs. Usually, an RPG program does not consist of a few program or procedure calls in a relatively short mainline. It usually consists of a substantial mainline with occasional calls to subroutines or procedures. There is relatively little need or use of the top-down paradigm, or conceptual model. It is possible to do it in RPG, but the very layout of the language does not encourage it. For example, I recall being amused years ago by an RPG program that had only one one line in its detail calculations; it did all its work in a subroutine named DETAIL, which was called by the calculation   EXSR    DETAIL. The very phrase “service program”, used today to refer to a collection of often-used routines into one module, suggests a servant pressed into duty of a superior routine, rather than a coequal partner in the main processing. The name “subroutine” has the same connotation, even if the subroutines do the bulk of the processing. They are subordinate, called by the main “detail” routine.

As RPG is currently constituted, I would consider this the most effective way of using the language. For example, there is the concept that all file handling operations should be consigned to a service program, which would then handle accessing, inserting, deleting, and updating records in a given file. I know I’ve seen the concept recommended, though I can’t give specific  examples offhand. But when  file handling is so easy in RPG, why bother with a service program when you can do it directly?   ACCT#    CHAIN   MASTER.

So I’m up against a wall of habit and preconceived ideas as I continue to try to expand my horizons, and perhaps my effectiveness, by learning a language built on new concepts and that can be completely described (in the official report on the language) in 16 pages of normally spaced text. Just for comparison, the report for C++ is 740 pages in length. (I am already acquainted with BASIC.)  If I can’t learn Oberon, there’s not much point in trying others.

Operating systems and programming style

January 11th, 2009

A few days ago, I was editing a program in WebSphere, the IBM-supplied Windows programming environment. I was scrolling the screen when, without warning, the program died. I was presented with the disappearance of WebSphere, replaced by a message box: “Eclipse” in the Windows header line, followed by the message line “JVM terminated. Exit code=8096.” This was followed by informative details like “Xquickstart” | “Xms40m” |, “Xmx768m”,…    I’m sure you get the picture. Thirty-one lines of error message. To anyone but someone in tech support at WebSphere HQ, totally useless. And if you did a print screen and found an e-mail address to send it to, their first response would be, “What exactly were you doing when it happened?” and the second would be “Could you replicate your error?”; since I wasn’t logging my keystrokes, just doing my job, all I could tell them was “Scrolling my screen” and “No.”

But this is getting to be a bit of a rant. What I really want to mention is how my background affected my reaction.

I started on an IBM System/3, then graduated to a System/34, then System/36, then AS/400. IBM midrange all the way. All of these systems were rock solid. Probably no computer user who has not worked on one of them (except perhaps mainframe people) can appreciate this. In almost 30 years of experience, I have NEVER had a system go belly-up on me. No blue screens of death. No “Illegal operation” errors. If a program crashed, it was because I or some other programmer had made a mistake, and the system usually told me very clearly the source of the error. No “exit code=7096″. If it gave you a message code, it also told you what the code message said.

And even Unix people, users of the other supposedly rock-solid operating system, have no reason to be smug. For example, I remember working with a Unix guy on a project that involved running RPG on a Unix box. In the course of his work, at one point, his cursor disappeared (!)  Not dismayed, he entered: “tty” (and remember, he couldn’t see what he was typing), hit a control key combination, then “sane” (Cute. The keyboard was insane, and he would restore its sanity.) .  And it worked. On the IBM midrange, such shenanigans were unnecessary. You never lost your cursor. And as for Linux, there have been countless times, while I was working in Linux, that the system locked up when I wasn’t doing anything more than what any other normal, non-technical user might be doing.

When you work on operating systems like the Midrange boxes had, you get spoiled. And, I have found, your programming style is affected. It may be the old batch processing mentality getting involved here, but if you have been a long-time user, you tend to be more careful. My Unix friend was of the sort that would throw together code on the fly and immediately run it, without any sort of desk-checking. I suppose he was of the sort that would let the debugger catch the errors, if the program didn’t show that it was wrong by crashing. I and others on my chosen platform tended to desk-check more. I feel that the more you examine your code, the less likely concealed errors will evade your notice. (And the devil-may-care problem solving process seems to be an issue with programmers of both Windows and  Unix background.) Maybe it was better that debugging facilities in early RPG were so lousy- you inserted a temporary DEBUG opcode into your calculations.

I guess when you are on the Midrange, you are less tolerant of casual errors. When your operating system spontaneously self-destructs, you are not overly concerned when your program you wrote self-destructs. Just hit Ctl-Alt-Delete, and everything will be okay.

I know I probably haven’t proven that Midrange programmers (and by extension RPG programmers, since most Midrange programmers write RPG :) ) are better than programmers on other systems. I probably didn’t prove much of anything. All I know was that my fellow programmers knew exactly what I was talking about when I did a print screen of my Web-Sphere message and gave them a printed copy with my caption: “The difference between the AS/400 and a PC.”

When and How to Upgrade Code

December 30th, 2008

I work on code that, when I came to work for my client, was essentially RPGIII/RPG400 or older. Some of the code had been implemented way back in the 1970’s and was migrated forward as newer machines were installed. And the code showed it. (I have found interesting the large number of 80 and 96 byte files in some of the systems, remnants of old punchcard processing programs.) You haven’t lived until you’ve attempted to update a program that has grown over the years to be a 10000+ line, indicator-laden monster. If you’ve been away from the program awhile and you need to make a non-trivial change, you need to spend part of a day, at least, reviewing the program’s processing.

I am normally conservative about program changes. I generally do not rip apart code and rewrite it, especially if it is not broken. But if a program is to be revised, I do generally at least convert it to RPGIV before making even a minor change. As a phrase used by one of my favorite literary characters (Anne of Green Gables) says, doing this allows “more scope for imagination”.

I was making code changes for a conversion project I was working on when I came across a particular program I had seen before and shook my head at. But for some reason, this time something snapped. I just HAD to change a particular chunk of code, even though the code in fact worked. No errors. But how far to change it? I will explain what I did. In the end, what I do will likely be seen as good by some, too intrusive by others, and  not radical enough by still others.

Read the rest of this entry »