Do you wanna be a software engineer?
Do you wanna work with one of the most in-demand and bleeding-edge technologies out there?
Do you wanna create lots of POSITIVE IMPACT and SOCIAL CHANGE?
Do you wanna live life in the fast lane?
Well, I got the language for you if you wanna dance like it's 1959 again. Introducing COBOL, the language that makes C look like child's play.
COBOL, or Common Business-Oriented Language, is a highly-verbose compiled language designed to run on mainframes powered by operating systems like z/OS from IBM. Designed in 1959, it was heavily inspired by the FLOW-MATIC language designed by Grace Hopper which features the same imperative and verbose syntax. The sole purpose of the language is to handle massive amounts of throughput in industries including airline ticketing, insurance claims, banking, and unemployment claims.
So you might be wondering, why are we relying on such an old language to process business-critical transactions that affect millions of people? It is certainly not popular as indicated by its low ranking in the TIOBE Index and with the advent of new/established languages such as Java, Python, and Go, new programmers have little reason to explore the world of COBOL.
The interest to upgrade and change is there, but businesses that rely on COBOL are stuck between a rock and a hard place. First, the cost of replacing all of the existing infrastructure and code base with a newer language can be very time consuming and costly. In 2012, the Commonwealth Bank of Australia took on this herculian task to transition its systems from COBOL to SAP ABAP. In total, the update took 5 whole years, 1 billion Australian dollars (USD 749 million), and the assistance of 2 other companies (Accenture and SAP). Upgrading isn't impossible, it's just extremely costly.
According to Reuters, it seems that COBOL won't be going anywhere anytime soon. Also with the lack of COBOL developers to help with the migration, it looks like these systems would be here to stay for years to come. With the Coronavirus outbreak, the lack is more apparent than ever as unemployment processing systems in New Jersey were failing under the spike in unemployment claims. It's not that the system was failing its job, but the changing environment has made it inadequate.
"We have systems that are 40-plus years old. There’ll be lots of postmortems, and one of them will be how the heck did we get here?, when we literally needed COBOL programmers." - Gov. Murphy of New Jersey
When I first heard him say this on the news, I thought it was a joke. I initially thought that a majority of our systems would've at least been upgraded to something newer, but I guess I was just uninformed.
Unexpected pic.twitter.com/A00tViNxJt— michael_nielsen (@michael_nielsen) April 4, 2020
If COBOL is trending on Twitter, then you know it's serious.
Now that I've got you on board, time to teach you to become a full-fledge COBOL developer. So now, we will start with the most important step to becoming a COBOL developer, writing "hello world".
But before that, we need to do a couple of things to get it up and running on your machine. For this guide, I will be using Ubuntu. This should work the same on the Windows WSL with Ubuntu.
First, we need to install a COBOL compiler. For this, we will be installing
sudo apt-get install open-cobol
Now, we can begin writing our program. If you were to ask me what the program structure looks like, it is a cross of MIPS Assembly and FORTRAN.
We start with different sections of the program. The
IDENTIFICATION DIVISION is used to store program properties and the
PROCEDURE DIVISION stores the functionality. Inside the
PROCEDURE DIVISION, we will use the
DISPLAY command to directly write to the screen. To end the program, we add the
STOP RUN command at the end, much like adding
li $v0, 10 in MIPS.
Open a new file in any editor and call it
*.cbl are file extensions for Cobol source files.
000000*> My first COBOL program. 000100 IDENTIFICATION DIVISION. 000200*> Identifies the name of the program 000300 PROGRAM-ID. HELLO_WORLD. *> Instructions go here PROCEDURE DIVISION. DISPLAY 'Hello from COBOL :)'. STOP RUN.
You may have noticed a couple of things about the code itself. The first 6 digits are reserved for line numbers that increment
100 per line. Comments are defined with
*>. Each program statement ends with a period, much like the English.
To compile this program, simply use
cobc -x hello.cob
The compiler should generate an executable file that you can simply execute with:
And there you have it, your first Cobol program!
This will be a quick overview of different aspects of the programming language. If you're interested, I recommend taking a look at the references I used to understand the language. Surprisingly, the documentation isn't too bad.
- Each line of the source file is offset 6 spaces to the right to account for the line numbers.
- Programs have different sections labeled with the
DIVISIONkeyword to separate the responsibilities of each part of the program.
- The first division is the
IDENTIFICATION DIVISION.which stores the metadata that describes the program (docs).
PROGRAM-IDparagraph allows you to specify the name of the program (docs).
- There can be other paragraphs, but those are optional.
- The second division is the
ENVIRONMENT DIVISION., which is an optional section where you can define program configuration and inputs/outputs (docs).
- The third section is the
DATA DIVISION.that specifies the internal and external data the program will work with.
- The variables must be specified in the
- The variables must be specified in the
- Last but not least, the
PROCEDURE DIVISION.is essentially the
main()function of our program. All of our wonderful spaghetti code goes here.
IDENTIFICATION DIVISION. PROGRAM-ID. MY-PROGRAM. DATA DIVISION. WORKING-STORAGE SECTION. *> Variables go here. PROCEDURE DIVISION. *> Functionality goes here.
Variables are pretty unique in COBOL. Instead of defining a type, it seems you specify what the variables hold as a composite of different types:
- A - alphabetic
- X - alphanumeric
- V - decimal
- S - sign
- 9 - numeric
For example, a floating-point number with 3 digits and 2 digits of precision would look something like this:
01 MY-FLOAT PIC S9(3)V9(2). VALUE +987.65.
Note that a value does not need to be specified for the variable. The best way I can sum up variable declaration is that we use the different symbols to represent the structure of the value that will be stored, much like how regex can be used to match different words/expressions.
The numbers appearing on the left-hand side specify the level of the variable for nesting data just like how classes/struct can be used to wrap around other variables.
01 PERSON-ADDRESS. 05 HOUSE-NUMBER PIC 9(4). 05 STREET PIC X(24). 05 CITY PIC X(24). 05 COUNTRY PIC X(24) VALUE 'BELGIUM'.
This is a very brief overview of variables, but I highly recommend looking at documentation from IBM to learn more.
Conditionals are quite self-explanatory given how it reads like plain English barring a couple of symbols.
PROCEDURE DIVISION. *> Initialize variables with numbers MOVE 30 TO A. MOVE 20 TO B. MOVE 30 TO C. IF A > B THEN DISPLAY 'A > B' IF A = C THEN DISPLAY 'A = C' ELSE DISPLAY 'A != C' END IF. ELSE DISPLAY 'A <= B' END IF.
For switch statements, we specify the value to
switch on (statement in Java) to be
EVALUATE TRUE WHEN A < 20 DISPLAY 'A IS LESS THAN 20' WHEN A < 30 DISPLAY 'A IS LESS THAN 30' WHEN A < 40 DISPLAY 'A IS LESS THAN 40' END-EVALUATE.
Conditionals can also be combined with
OR, and some others.
IF A IS LESS THAN B AND A IS LESS THAN 50 THEN DISPLAY 'THIS IS IN FACT TRUE' ELSE DISPLAY 'THIS SHOULD NOT SHOW' END-IF. *> Combined conditional without else IF A IS POSITIVE OR A IS NEGATIVE THEN DISPLAY 'A IS POSITIVE OR NEGATIVE'.
For further reference, there is a lot written about how to implement conditionals.
There are a lot of other aspects of the language not shown here such as commands, strings, loops, file I/O, etc.
Can COBOL be used for Leetcode? Absolutely. Allow me to demonstrate.
For today's problem, we will be doing Leetcode 326. Given an integer, write a function to determine if it is a power of three. And for the follow-up, could you do it without using any loop / recursion?
For the solution below, we will accomplish both. The first solution that comes to keep dividing the given number,
n, by 3 and see if the remainder is 0 at the end. However, that did not fit in with the follow-up and I got too tired to figure out how to write a loop, so we will use the change of base formula instead.
i = logb(n)/logb(3)
IDENTIFICATION DIVISION. PROGRAM-ID. POWER-OF-THREE. DATA DIVISION. WORKING-STORAGE SECTION. 01 SAMPLE-INPUT-1 PIC 9(8) VALUE 27. *> Future assigned variables 01 LOG-10-VAL USAGE FLOAT-LONG. 01 LOG-10-3 USAGE FLOAT-LONG. *> Quotient should be an integer. 01 QUOTIENT PIC 9(10). *> Floating point with 4 bits of precision. 01 LEFTOVER PIC V9(4). PROCEDURE DIVISION. *> Get the log base 10 value of n COMPUTE LOG-10-VAL = FUNCTION LOG10(SAMPLE-INPUT-1). *> Get the log base 10 value of 3 COMPUTE LOG-10-3 = FUNCTION LOG10(3). *> Divide the log values and get the quotient and remainder DIVIDE LOG-10-VAL BY LOG-10-3 GIVING QUOTIENT REMAINDER LEFTOVER. *> If the remainder is 0, *> 3^i for some integer I equals the input IF LEFTOVER = 0 THEN DISPLAY "Input is a power of 3" ELSE DISPLAY "Input is not a power of 3" END-IF. STOP RUN.
I seriously hope they never ask Leetcode questions in COBOL. Ever.