Don't hate COBOL until you've tried it

It's the Rodney Dangerfield of computer programming, but COBOL is still in use—and really does deserve respect.
485 readers like this.
What to like about COBOL

Rainer Gerhards. Modified by Opensource.com. CC BY-SA 4.0

COBOL is the Rodney Dangerfield of programming languages—it doesn't get any respect. It is routinely denigrated for its verbosity and dismissed as archaic. Yet COBOL is far from a dead language. It processes an estimated 85% of all business transactions, and 5 billion lines of new COBOL code are written every year.

I worked for 10 years as a COBOL programmer, and I don't think it's quite as bad as its reputation would lead one to believe. In fact, it's quite good at handling currency and fixed-format records. But COBOL does have its quirks, many of them rooted in the computing environments of the early days of programming. This is a story of how a punch card ate my program.

A mysterious bug

Here's an example of the problem code, which tries to compute the shipping charge and expected shipping date for an order:

 1      identification division.
 2      program-id.
 3          test-ship.
 4
 5      data division.
 6      working-storage section.
 7
 8      01 shipping-method            pic x(2) value 'US'.
 9      01 cust-type                  pic x(2) value 'EM'.
10      01 normal-ship-date-yyyymmdd  pic 9(8) value 20170522.
11      01 nextday-ship-date-yyyymmdd pic 9(8) value 20170508.
12      01 expected-shipping-date     pic 9(8).
13      01 shipping-charge            pic 99v99 value 4.99.
14
15      procedure division.
16          if shipping-method <> 'FX'
17              move normal-ship-date-yyyymmdd to expected-shipping-date
18          else
19              move nextday-ship-date-yyyymmdd to expected-shipping-date.
20
21          if cust-type = 'EM'
22              move 0 to shipping-charge.
23
24          display expected-shipping-date.
25          display shipping-charge.

The logic should be easy to follow, even if you've never seen COBOL code before. If the shipping method is "FX," the customer gets next-day shipping, otherwise shipping takes two weeks. (This was the '90s.) Employees get free shipping; everyone else pays $4.99. This code looked correct to me, but it has a bug—the shipping date is calculated correctly, but employees are charged full shipping.

The problem turned out to be the period at the end of 19. Back then, it took some detective work to track this down, but modern syntax-highlighting editors would flag it immediately. But why was this a problem? Why didn't COBOL like that period, when it was perfectly happy with the one at the end of line 22?

Sentences instead of blocks

To answer that question, we need to go back to COBOL's origins in the late 1950s. Until then, most languages were designed to solve scientific and engineering problems, so their syntax resembled mathematical equations. (Fortran is the classic example of this type of language.) COBOL, on the other end, was intended for business computing. To make it easier for lay people to learn, Grace Hopper and her team of Defense Department and IBM engineers gave COBOL an English language syntax. Instead of the recursive syntax most modern languages have, COBOL programs have a hierarchical structure. Instead of blocks, COBOL groups statements together into "sentences." And just like in English, each sentence is terminated by a period.

While this may have seemed like a good idea in theory, in practice it proved to be problematic. It made it hard to move code around, since a stray period might terminate a block unexpectedly. Periods were also hard to notice—they were often just a single pixel on '90s-era CRT terminals. But there was a deeper problem here, one that relates to how programmers wrote code when COBOL was first developed.

Punch cards

COBOL punch card

opensource.com

Hard drives were prohibitively expensive when COBOL was designed, so most programs were written on punch cards. The most common punch cards consisted of a 12x80 grid, where a hole represented a 1 and a non-hole a 0. Each column was a single 12-bit character, and each card was a single 80-character line of text. To run your program, you'd feed a deck of punch cards into a card reader. The first six and final eight columns of each card were reserved for sequence numbers and identifiers. That way if you dropped your deck—which might be your only copy of your program—you could feed the cards through a mechanical sorter to put them back into the correct order.

What this means is that COBOL ignores any characters after column 72. If that happened to be a period, the entire logic of your code could change. And, as you've no doubt guessed by now, that period on line 19 was in column 73. Here's how the COBOL compiler actually interpreted those lines:

16          if shipping-method <> 'FX'
17              move normal-ship-date-yyyymmdd to expected-shipping-date
18          else
19              move nextday-ship-date-yyyymmdd to expected-shipping-date
20
21              if cust-type = 'EM'
22                  move 0 to shipping-charge.

Once I discovered what the problem was, the fix was easy: I deleted one character of white space from the beginning of line 19, which put the period at column 72. Although I'd never encountered it before, this was such a common bug that many mainframe COBOL programmers would tape a piece of thread between columns 72 and 73 on their terminals.

COBOL today

The COBOL-85 standard added scope terminators like end-if, so periods were no longer necessary to end sentences. The COBOL 2002 standard allowed free-form code, although many compilers had support long before that. The same code written to the 2002 standard looks more like a modern programming language:

16 if shipping-method <> 'FX'
17     move normal-ship-date-yyyymmdd to expected-shipping-date
18 else
19     move nextday-ship-date-yyyymmdd to expected-shipping-date
20 end-if
21
22 if cust-type = 'EM'
23     move 0 to shipping-charge
24 end-if

Note that the white space at the beginning of the line is also no longer necessary. The system I usually worked on supported both scope terminators and free-form code, so I never ran into this issue until I had to make some changes on another system.

Learning about COBOL has been difficult for open source enthusiasts. COBOL compilers have traditionally been closed source and expensive, and most COBOL code is written in corporate environments. However, work on an open source compiler called OpenCOBOL began in 2002. In 2013, it was officially accepted as a GNU package and renamed GnuCOBOL. To learn more about GnuCOBOL, including accessing the 400-page programmers guide, visit the project's homepage.

Learn more about COBOL in Walt Mankowski's talk, A Punch Card Ate My Program!, at FOSSCON August 26th in Philadelphia.

User profile image.
Walt Mankowski is a recovering ivory tower computer scientist who recently completed a postdoc working with biologists to process and visualize terabytes of 2D and 3D time lapse microscope images. In his past life he spent 10 years as a COBOL programmer at a major cable home shopping network. He enjoys Perl, regular expressions, high-performance computing, and Futurama.

39 Comments

Thanks for a great article! I did some COBOL early on in my professional career, and am still a fan.

I've been using the COBOL-85 standard for thirty years, and never had a issue with periods. In fact, every paragraphs I write ends with an EXIT statements and the last thing in the paragraphs is a PERIOD on the line before the EXIT.

Be disciplined in how you code the procedure division; innovative and methodical with your WORKING-STORAGE SECTION, and there is nothing you can't do with COBOL.

1000-PARAGRAPH.

IF
blah blah blah
END-IF
.
1000-EXIT. EXIT.

:)

Just a minor nitpick... Column 72 was special. If it contained either a hyphen or a "C" then the compiler was supposed to take the next line and append it as a single line for processing.

To be honest, the system I used 99% of the time used free-format code, so this never came up. But everything I can find online says that a continuation was indicated by a "-" in column 7, which meant the current line should be appended to the previous line. I can't find anything to indicate that column 72 was treated special. Perhaps you're confusing it with another language?

In reply to by Martin DiViaio (not verified)

Sorry... But it was definitely column 72. It's been more than 30 years so I forget if it was part of COBOL66 or the ANSI COBOL 74 "standard." I do remember someone trying to use it way-back-when until the sysadmin told him to use shorter variable names and move on.

In reply to by waltman

I have been an IBM mainframe software developer since 1983. It is column 7 that is special, not 72. A '-' denotes a continuation from the previous line, a '*' denotes a comment line and a '/' is a compiler directive to force a page break in the compiler listing. Anything else is NOT the standard.

In reply to by Martin DiViaio (not verified)

It appears that JCL and some mainframe assemblers used column 72 to indicate continuation, so I guess it's possible some early version of COBOL did as well.

In reply to by Scott Spurlock (not verified)

If I'm remembering correctly from back in the 1960s, hard drives didn't exist at the time COBOL first came out. Mainframe computers saved data on magnetic or paper tape.

IBM released their first hard drive, the IBM 305 RAMAC, in 1956. That was a few years before COBOL, which dates to 1959. Hard drive storage was extremely expensive, which is probably why they were still uncommon.

In reply to by Greg P

As I look this up, it does seem hard disks existed, though it's not clear how they were used, since they typically had only a few MB of storage space at first.

In reply to by Greg P

Right. I have a picture in my talk of workers in 1956 moving a 5 MB hard drive that's the size of several refrigerators. But then, the first PC hard drive I ever used only had 3 MB of storage, and it seemed enormous!

In reply to by Greg P

It's called bloatware. Today's computers and phones are full of it.

Back in the stoner age, ('60s and '70s) you sometimes had only 40 KB of mainframe space to run a program in.
So you worked very hard to make it fit. And if it couldn't be done in COBOL, then you did it (at least some of us did it) in Assembler.
Unlike today's hotshots, only the strong survived.

In reply to by Greg P

I began programming in the early 80s on those early PCs. When I was an ivory tower computer scientist, I still had a PC, but it had 32 CPUs, 64 GB of RAM, and terabytes of storage. We were able to work on computational problems that were unthinkable back then. Also programming's already hard enough without having to micromanage memory. While it's fun to look back, it makes me appreciate modern hardware and software even more!

In reply to by aqk

Stoner age? Guess you don't know what we have today Haha.

In reply to by aqk

You ain't seen nuthin, until you've seen a COBOL program being compiled on a 4K Remington-Rand Univac-II with 12 big tape drives, all of them spinning at once. In the early 1960s, a small program would take about 1 to 2 hours to compile.
But once the IBM 360 was introduced in ~1965 with its big 2311 disk drives - 7 Meg each! - that program would compile in less than 10 minutes.

And yes, that was 4K, not 4 Meg.

In reply to by Greg P

Disk drives become common in the mid '60s with the release of IBM's 360 set of computers and operating systems. A welcome relief for someone trying to compile a COBOL program on a Remington-Rand Univac-II with 4K of RAM and 12 big magnetic tape drives.
You shoulda seen all those tapes in action as a small COBOL program was being compiled. It usually took 1 to 2 hours (run overnight naturally)
(mutter mutter... curse you, Grace Hopper...!)

** and yes, that was 4 K ! Not 4 MB.

In reply to by Greg P

Did Cobol long time ago and I still like it! Simple and easy to understand. If I want to write a line of code today, I have to install 25 open source tools and libraries, hack some command line stuff and pray before anything comes up.

When you put an asterisk in column 7, it turned the rest of the line into a comment. And guess what, I had one which commened out a GOTO statement. (Ops)

Column 7 & 72 work together. 7 has a few purposes but it can be used in combination with 72 to denote continuation & concatenation of several special cases involving national character sets (multi-byte sequences resolving to a non-Latin character code). See: https://www.ibm.com/support/knowledgecenter/en/SS6SGM_3.1.0/com.ibm.aix…

Another minor observation or piece of trivia regarding the punch card.
Very few of today's programmers/ IT "specialists" realize that the 80 character text line (in an editor or on a terminal screen) comes from the 80 columns of the 120 year old (at least!) Hollerith punch card eventually adopted by IBM data processing, before the programming library finally made it in the 1970s onto magnetic tape (briefly) and thence to disk.
Alas, Herman Hollerith died long before COBOL was even a punch in Admiral Grace's 80 column card.
If you wish to make a case for it, you could probably even argue that these punch cards were first developed in the 18th century by textile weavers.

Addendum: Before anyone attempts to go back further in history:
Some folks claim that the width of the punch card (or perhaps its length) was originally based upon the width of the track made by a Roman chariot's wheels and its peculiar rectangular indentations in Roman roads of 2000 years ago.
Nonsense! As with the claim that the size of the Saturn-1 rocket booster is based upon the Roman road, this is just another urban legend. ;-)

In reply to by aqk

The reason I heard is that Hollerith made them the same size as the US dollar bills of the time.

In reply to by aqk

The limited capacity and the cost of hard drives had something to do with the use of punch cards (in terms of storing programs), but there was also the problem of a lack of inexpensive terminals. At the University of Maryland in the late 1970s, there were a limited number of ASCII teletypes available to students, which meant the bulk of the students had to use punch cards. (While I was there, the teletypes were replaced by DECwriter-like dot-matrix keyboard/printers.) The UNIVAC mainframes' magnetic drums had been replaced by hard disks, but the OS continued to provide the drum API which simulated the drum on the hard disks.

I've only used COBOL once, in a database class in 1981, but I'd read Daniel McCracken's classic book on COBOL several years beforehand (as well as his books on Fortran and Algol). I had no problems using COBOL; every programming language requires a different mindset and getting to know COBOL (in that limited amount of time) was just as intellectually satisfying as getting to know all the other languages I've used.

Back in the 1990s, I think, a COBOL evangelist used to post frequently on a USENET newsgroup, either comp.os.unix or comp.lang.c. He wasn't focused primarily on COBOL; it would just come up now and then. In one post, he presented a *complete*, *portable*, 4-line COBOL program to sort a file. (As I remember it ...) The portability was possible because COBOL has a sort capability built-in and most other languages don't. Using an OS-specific system call in another language to, say, run an external "sort" program is not a portable solution.

I went to Penn in the early 80s. I never used punch cards, but there was still a lot of old hardware that was gradually being phased out. But I was really talking about the very early days of COBOL. Computer terminals didn't start to be available until the early 70s, and COBOL had already been in use for a decade by then. Teletypes were around earlier, but I'm not sure how well they'd work with mainframes since all the ones I ever saw required a bisync connection.

Today when I program in languages like C++, Perl, or Python, I'll often wonder if there's a better way I could be coding something. Should I use a hash or an object? A structure or a class? A loop or a list comprehension? I never did that in COBOL, because there usually was only one way to do anything. It might not be a great way, but it's how you did it. And so most of my energy was devoted to solving business problems instead of language problems. Of course it also gets frustrating when you know there are all these better ways to do things, but sometimes a lack of options can help focus the mind. :)

In reply to by Alex Measday (not verified)

Great article. I'm glad to see COBOL is still alive and used heavily.

I am a COBOL compiler developer for one of the major Main frame companies still alive.

One OF the mainframe companies? You mean Amdahl and Hitachi are still in the game?
45-50 years ago it was just "Snow White" and the Seven Dwarfs.
Extra points if you can name me those poor seven!

In reply to by User

A question... Which version of COBOL added the ELSE clause to IF statements?

I was on a team of DBAs that had do data extraction and conversion from a mainframe database for Y2K using a COBOL that did not support an ELSE clause. We called it "COBOL I" but I can't find online references using that name.

That's bizarre! I can't say I've ever heard of any programming language that didn't support ELSE. If you wanted to do the equivalent of ELSE, did you have to repeat the IF with the negation of the condition? Did your COBOL run on a mainframe or on some other platform?

In reply to by DocSalvager

Jean Sammet listed "A powerful conditional (i.e., IF THEN ELSE) structure" as one of the core contributions of the first version of COBOL, COBOL '60. (See "The Early History of COBOL", by Jean Sammet, pp199-243, in History of programming languages I (1978).) I wonder if there was specific implementation trouble with the version you ran in to.

In reply to by DocSalvager

No, the problem was that the period in column 73 was ignored. I first saw it on the Stratus VOS compiler, and I was able to duplicate it in GnuCOBOL. It would have happened with any control structure.

In reply to by Jeff B (not verified)

But instead of the old compiler GnuCOBOL says "source text after column 72" :-)

In reply to by waltman

That was my first post and I don't see a way to edit it. What I meant was, what was the last version that did NOT support an ELSE clause?

I still utilize Cobol. All of my business' programs are in Cobol. Just finished working on a new program. GUI interface, MySQL database. Started on a IBM 360, then DEC10, 1970s. Then TRS80 model II and III, finally PC. Current server is Linux Debian, with WIN10 user machines. Works great and fast.

Nice article. I learned COBOL at the university in the 80s and did some programming in COBOL in the early 90s. I can't say that I liked it, but it did the job.
You mention that COBOL "processes an estimated 85% of all business transactions". Is there a specific source for this estimation?
Thanks

neat to see lower-case in the cobol code.

i was doing that decades ago; no one else. was fun to find out that the code compiled just fine. can't stand all upper-case as IT IS ALWAYS SHOUTING AT YOU. UGH.

Our codebase was all lowercase. Perhaps they did it that way because we were on Stratus computers, not mainframes? I never thought to ask anyone.

In reply to by dwight (not verified)

I have lot of programming work in Cobol. I also used the punching cards as an input for programming work. Initially the statements are keyed in and punched and then read card reader as shown in one of the blogs.I worked on PDP/11 for all business applications.
It was very easy to write the code and even my heart goes to Cobol. Later I wrote the programmes in MF Cobol, RM Cobol, MS Cobol for 10 years between 1984-1994 when I was working Middle East for IBM computers. And I also wrote several programmes in AS/400 Cobol/400. I think I would be happy to write the code in Cobol even today. Good Luck.Good work I did in Cobol

Creative Commons LicenseThis work is licensed under a Creative Commons Attribution-Share Alike 4.0 International License.