Maybe you think that the COBOL Developer-shortage is not so bad, because you can hire non-COBOL Developers and train them in COBOL. This sounds reasonable, because after all, COBOL is supposed to be so very „readable“.

But why, then, do 70% of COBOL programmers utterly hate it? Even I have a hard time making sense of this: A programming language, that is hardly still on the TIOBE index being in the Top-3 of the most hated programming languages? How bad can a language be!?

I’ll admit that COBOLs DISPLAY "Hello, World!" tells you more clearly what it does than printf("Hello, World!\n"); in C or even PRINT "Hello, World!" in BASIC… does it make the printer print a page that says „Hello, World!“? (actually it did, back in the days before the invention of monitors).
Also ADD X TO Y tells you more clearly what it does than ADDW X Y (or was it ADDW Y X?) in Assembly.

But programs consist of complex combinations of just a few, fundamental building blocks. Sure it’s nice when these building blocks are self-explanatory, but in a professional environment I think I can expect someone to know the few fundamental building blocks of their language in and out – whether they are self explanatory or not.

Also, in a professional environment, you have large programs – you use these building blocks a lot. Therefore, in a professional environment, it is more important to have short fundamental building blocks. To an experienced programmer, { and } are as readable as THEN and END-IF, but { and } are quicker to write. So { and } make you more efficient. This turns COBOLs undeniable verbosity into a disadvantage.

Not all fundamentals are so readable.

In my opinion, many of the fundamental building blocks of COBOL aren’t even as readable as people claim. It might have started out that way, but over time, COBOL has been extended and extended – and the developers apparently preferred adding modifiers to existing verbs over adding new verbs. As of 2020, IBM COBOL has over 500 keywords! They apparently didn’t like reusing the same word for modifications of different verbs. The result is, in my opinion, a complete mess of „natural language“ syntax. The verbs may be clear, but their modifiers became more and more arbitrarily chosen words, slapped together in a mostly random order and they aren’t even consistent. For example sometimes you have to separate two words with a space, sometimes with a dash.

This makes every verb as complicated as a complete programming language. Learning COBOL thoroughly is, therefore, as hard as learning at least 30 other programming languages at once. Sure – when you know a few verbs and a few modifiers of them, you’ll already be able to write your own small programs, but when you try to read someone elses code, they will probably have used lots and lots of verbs and modifiers that you don’t know yet. And – worse – you will always be wondering if the word you are looking at even is a verb/modifier you don’t know yet- or just a variable-name.

The really primitive things, such as conditions, performing paragraphs, mathematical computations and displaying text and data – these are readable enough.
But why is „ACCEPT“ the verb to prompt the user for input? Why do out-of-line loops have such mind-boggling exit-conditions? Why is the declaration of variables such a mess? Do you really think someone understands
01 WS-A.
02 WS-B PIC X9(5).99X OCC 5.
without any explanation? Would you understand B-AND and B-NOT without prior knowledge from other programming languages? Handling files with indexes, Sorting, Searching and nesting loops with PERFORM-AFTER (at least in some COBOL-dialects) are so unclear that I even had to write multiple test-programs to nail down how they behave.

What vs. How

Do you remember QWOP? That old flash game where you control 4 muscles of a runner individually?
You can perfectly understand the effect of each indiviual key, but you will go crazy before you get the runner to make a single step forward.
In programming, it is similar – just because you know the fundamental building blocks doesn’t mean you understand what a combination of them does.

When I still went to university, I sometimes taught tutorial courses and I remember one student, whose homework was commented like this:

int a, b, c;      // declare variables a, b and c
std::cin >> a;    // read a
std::cin >> b;    // read b
while(b != 0) {   // while b is not equal to 0
    c = a % b;       // set c to remainder of division of a by b
    a = b;           // set a to value of b
    b = c;           // set b to value of c
}                 // end of loop
std::cout << a;   // display value of a

Yes, I can read the fundamental building blocks of C++, thank you.

The problem with these comments is that they don’t tell you what the code does. It tells you line for line how it does whatever it does. This is not a useful information for someone who tries to make sense of your code (like the person who inherits your code when you retire).

But this is exactly the extent to which COBOL codes are „readable“. You may be able to read the fundamental building blocks without introduction, but they only tell you what they do – they don’t tell you about their context. They don’t tell you why they are there. For well documented code, readability of the fundamental building blocks is irrelevant. And this immediately brings us to the next topic:

Missing Documentation

Back then, many COBOL programmers didn’t document their code, because „Hey, it’s COBOL! It’s self explanatory! I don’t need to comment it!“

This is a huge problem today – people just cannot inherit other peoples COBOL codes, because they cannot make sense of these codes. The codes might as well be encrypted.

Also take into account that the authors have very little incentive to do anything about this. Being the only one who can work on an essential part of a companies core software makes you absolutely indispensable for that company. They would cut into their own flesh if they started documenting their codes or explaining them to someone else now.

This is a widely acknowledged problem:

So COBOL only gives you the irrelevant kind of „readability“.

A language-barrier of its own kind

A few years ago, at the company where I worked at the time, we had a problem with a COBOL program and the responsible colleague was on vacation. So I tried reading the COBOL code and didn’t understand anything. Mind you – this was at a time when I had already worked with over 20 other programming languages! So I picked up a book about COBOL and started reading that – and then I understood even less.

The problem I had is that, in the COBOL environment, people used their own vocabulary, which is quite different from the terminology that is widely used today. So even when the code is documented – you will have a hard time understanding the documentation.

Let me give you some examples: In COBOL you don’t have boolean variables, you have Level-88 variables (how self-explanatory!). You don’t save a file – you catalog a dataset (because you don’t have a file system, you have a catalog) and you don’t save it on a hard-drive, you save it on a DASD (Direct Access Storage Device). You don’t boot your machine, you IPL it. You don’t have an operating system, you have a control program. It doesn’t have a kernel, it has a nucleus. You don’t sort an array, you collate a table. You don’t have a debugger, you have an execution diagnostic facility. The compiler doesn’t produce object files, it produces object decks. You don’t have a linker, you have a binder and it doesn’t produce an executable binary, it produces a load module. You don’t call a function, you perform a paragraph. Even the word „program“ means something different in the COBOL-world. What COBOL programmers call a „program„, I would call a „static method“ – but this is debatable, since on the mainframe, you kind of invoke these methods directly from the command-interpreter. By the way: in that command interpreter, you don’t have processes, you have jobs and you don’t run scripts, you submit job-cards – a term that comes from punched-cards!

So when you read COBOL codes, you even have kind of a language barrier on top of the problems above.

The ultimate challenge

We can debate this topic for hours, but I think I can settle it with this challenge: either you tell me what this tiny little program does (without looking it up) or you admit that COBOL is not really readable.

IDENTIFICATION DIVISION.
   PROGRAM-ID. MYSTERY.
DATA DIVISION.
   WORKING-STORAGE SECTION.
       01 WS-A.
       02 X PIC S9(6) OCC 4.
PROCEDURE DIVISION.
   ACCEPT X(1).
   ACCEPT X(2).
   PERFORM FOO UNTIL X(2) IS EQUAL TO ZERO.
   DISPLAY X(1).
   STOP RUN.
FOO.
   DIVIDE X(1) INTO X(2) GIVING X(4) REMAINDER X(3).
   MOVE X(2) TO X(1).
   MOVE X(3) TO X(2).

Come on! It’s only 7 effective lines, written in the most self-explanatory language there is! This can’t be hard!