I have not used COBOL for 30 years but the language deserves respect. The transition from assembler to COBOL was one of the biggest productivity improvements in the history of programming, comparable to the introduction of Java and VM-based programs in the 1990s.
COBOL is still pretty efficient for tasks like scanning data on magnetic tapes--not that most of us do that any more. In fact it was pretty good for any problem that involved reading from or writing to storage devices because you could control the data layouts very precisely. It was great on reports for the same reason. I even wrote a simple doc markdown processor in COBOL because the place I worked didn't have usable word processors and we needed something to do pagination and formatting of docs.
I don't miss the verbosity or the lack of modularity but on the other hand COBOL was an effective tool that you could use to solve problems more quickly than other tools available at the time.
> one of the biggest productivity improvements in the history of programming, comparable to the introduction of Java and VM-based programs in the 1990s.
If languages like Smalltalk, APL and Lisp aren't counted, then sure, Java was big productivity boost in the history of programming.
I think that the reach of a language need to be considered, as influential and lovable those language might be most of the effect they had was by influencing other languages.
There's nothing wrong with that. Algol heavily influenced the design of scheme, but I've never seen an Algol program in the wild. That doesn't mean it wasn't influential.
Einstein got the Nobel for the photoelectric effect, which we take advantage of continuously every day. I'd say that was influential.
Fortran's older and Lisp is as old (it can be argued about whether COBOL or Lisp are older). Fortran and Lisp seem to have held up much better. ALGOL is another contemporary, and arguably the one that has the biggest impact on popular languages.
Just a note on FORTRAN (which I also used for about a decade) vs. COBOL. It's important to remember that FORTRAN could not deal easily with character data until FORTRAN-77 which introduced the CHARACTER type. Prior to that you stored character data in arrays of 4-byte words, INTs if I recall correctly. It was really painful to use for data manipulation and reports which were among the main forms of output at the time.
I'm also a big FORTRAN fan, especially the VAX-FORTRAN variant DEC introduced in the 1980s. It was great for numerical analysis but also included library calls to access the operating system, much like C. Some of us were late to the Unix party, so this was a huge step forward.
The best thing about COBOL is the distinct lack of hipster coders or frameworks. I worked on various COBOL code bases over the years, and they were always approachable, if a little long-winded.
My cheques still process via COBOL code a friend's grandmother wrote and still runs on emulated Unisys hardware.
Ah. I’ve been downvoted... Guess I should’ve been more clear. I was referencing how the OP said COBOL was easier for data layouts. So, not really knowing COBOL, I was asking why. Poor wording.
The feature we’re talking about here is an easy to use version of doing memory layouts like you’d do with C structs and unions. And combined in with that is automatic number formatting. And all of it uses a clean concise layout that’s self documenting.
COBOL structures are better for fixed-length strings than C structs are because C really prefers strings do be null terminated. In C you've got to specify the length of each string, whereas in COBOL the compiler takes care of that for you.
Now, recover a new Lisp struct instance from this binary struct:
3> (ffi-get *2 (ffi foo))
#S(foo count 42 name "ABCDABCDABCDABCD")
No problem; the FFI type system knows that an "array of char" is different from a null terminated string, and can make it correspond to a Lisp string in both directions.
Now, for fun, let's poke a zero byte into that buffer:
6> (ffi-get *2 (ffi foo))
#S(foo count 42 name "ABCD\xDC00;BCDABCDABCD")
What's that? My UTF-8 decoder treats the 00 as an invalid byte, and maps it into the surrogate pair range U+DCXX.
The otherwise optional semicolon was output because the next character in the string is a hex digit.
If that U+DC00 is encoded back, it will reproduce the null byte:
COBOL's data types look like they're well-suited to storing fixed-width, hierarchical data, with the format of the data being specified in the data type. The numerical types are oriented toward fixed-point decimal, with explicitly specified levels of precision.
Two variables holding common license plate formats might look like this:
01 LIC-PLATE1 PIC 9A(3)9(3) VALUE '1ABC234'.
01 LIC-PLATE2 PIC 9(3)A(3). VALUE '123ABC'.
[edit: added a newline to separate my examples]
("9" specifies a numerical digit, "A" specifies an alphabetic character, and there are other types that deal with sign, explicit and implicit decimal points, etc).
Assembly deals with memory layouts, but doesn't enforce any kind of higher-level data type, and especially not a human-oriented data specification.
Once in a while I decide I want to play with COBOL, so I install GNU COBOL, dig out my old test code and try to use it to do something interesting.
So, most recently I wanted to simply read a file, do some simple processing and then write an output file. Very basic, right?
Not so much with COBOL.
First you have to statically declare the files you want to use. Let's say you want to read from "foo.txt":
environment division.
input-output section.
file-control.
select foo0 assign to "foo.txt"
organization is sequential
access mode is sequential
file status is fs0.
You then need to declare (statically again, of course) the structure of the records in the file. You can think of this as global variables that gets filled in when reading from the file:
Then, you need to open the file. That's not too hard:
open input foo0.
Then you want to read from it. You can do that using the command:
read foo0.
After the read, the variable "fs0" will be 0 when you've reached the end of the file, so you need a loop that, I presume (I never got this part to work right), would look something like:
perform with test before until fs0 = 0
read foo0
* foo-name and foo-value now contains data from the file
end-perform
After all of this, I decided I wanted to do something different. I wanted to call a web service to load some information over HTTP. I dropped that project really quickly once I realised that the only way to do that was to use libcurl and directly access it using FFI. The FFI that is provided by GNU COBOL isn't really easy to work with, as evidenced by this discussion: https://stackoverflow.com/questions/26367026/how-to-make-htt...
If you look at the code that is linked from that page, you'll rather quickly realise why COBOL is not such a great idea for general purpose computing.
10 is EOF, 0 is successful read. Not that it actually matters, your point is perfectly valid. You can use sort off boolean operators thats toggled on based on the value in variables.
Outgoing web requests are usually done via either a program in some other language that you call from the COBOL application, or via DB2s built in functionality by running it as an embedded SQL section in your program. Why the heck web requests are handled by the relational database is.. Well I mean it feels odd, but by doing it that way they added the functionality to both zOS and IBM i at once. And old developers don't have to learn all to much new stuff to do it.
Also, while the COBOL program works with a static set of files with static filenames. Those names can point to any file by various overrides done in either JCL on the mainframe or CL on the IBM i/AS400. Regarding the file formats, you can read the file into different working-storage defined variables, so each row doesn't have to be identical field length/position. In short, COBOL is just one part of the solution. Various "scripting" languages play a large part in defining what files go in and out. And none of them are available outside of the actual mainframe/midrange environments. Most data is gathered from relational databases anyway nowdays, and embedded SQL, just like in PHP webpages of yesterdays web, is whats used in newly developed programs.
But all in all, yes it's a rather cumbersome language, for any sort of sane string handling you have to revert to embedded SQL. But most problems you have to write programs to solve can usually be broken down into smaller problems. Then just chain programs to handle it. The language itself is usually just a bit of a bother, but the age old programs written 20-30 years ago written by developers of varying degrees of sanity who had no requirements on them to document their work is what makes the job a pain.
It's certainly true that there's a lot of boilerplate verbosity involved in reading files in COBOL. But once you've done that, parsing out the fields will likely be much simpler than in most modern languages. Records like this are still produced at government agencies such as the US Census Bureau. I've often wondered if it might be simpler to do the parsing in COBOL and then pipe it to another language to do the rest of the processing.
On IBM i all files are are also databases, so you could just define the length of all the fields in the file, then it's a SQL database ready for use. No need for a program to parse it. Just define a file, copy the incoming file to that file. Ready to be handled with SQL. Fixed length records are trivial on the platform.
I have regualr talks with people who were using COBOL a while ago.
There are things were cobol is good :
1/ COBOL run in closed environments. This allows these to be rock solid.
(no such thing as a dependency nightmare). You don’t have such a thing
as different version of Java on your testing and production environment.
2/ COBOL forces you to mix concerns : DB access, file I/O, business logic.
This is sometimes useful to get a complete picture of what’s going on
in a program. In Java, you have to wander through your DAO, data model,
business logic, etc. which are spread everywhere.
3/ Code resue is hard to acheve so there is some copy/paste. That is sometimes
good in the sense that if you fix a program, you won’t accidentally introduce
a bug in a copy of that program. (many of us will scream at reading this, but
consider it).
4/ Of course COBOL programmers are good too and they use these old practices
in a sensible way
5/ COBOL technologies don’t change often. So there’s no discussion about
changing your framework. When you write software that must last for at
least 10 years, this makes choices easier.
I don’t think COBOL does force you to mix concerns. You could create sub modules / services which you call from a main program to do things like file writing or database reading.
Java doesn’t also say you have to separate concerns. You could easily write a single method which mixes business logic and IO (file and DB)
When writing a batch program you need a balance between understanding it, making it efficient and reliable and promoting re-use (e.g. if many batch programs want the same behaviour break it into a reusable module). COBOL still has dependencies too, so each program is rarely written in isolation and you have to co-ordinate with other teams to ensure their module versions are in sync with yours.
The thing that has always let COBOL down for me is the lack of automated testing.
>>> Java doesn’t also say you have to separate concerns.
Sure, I was talking from inside my own enterprise-context where Java actually means Java + Spring + a few other things that force you to separate concerns (for the better imho, although it doesn't help with code navigation)
>>> The thing that has always let COBOL down for me is the lack of automated testing.
I don't think most of those things are pluses for COBOL really, but if the alternative was what the Enterprise Java world has been doing for the past 10 or 15 years, bring on the COBOL.
> 2/ COBOL forces you to mix concerns : DB access, file I/O, business logic. This is sometimes useful to get a complete picture of what’s going on in a program. In Java, you have to wander through your DAO, data model, business logic, etc. which are spread everywhere.
Java doesn't force you. You can structure your code in many ways. In particular nothing is forcing you to have objects like Customer, Order, Invoice, etc. It is just the way OOP has been traditionally taught. Specifically in enterprise applications where a lot of the logic revolves around the data tables makes sense to have objects like CustomerTable, OrderTable, InvoiceTable and have all the related code encapsulated. See https://martinfowler.com/eaaCatalog/tableDataGateway.htmlhttps://martinfowler.com/eaaCatalog/transactionScript.html
All your points make a lot of sense. But it is not an essential part of the language. It is more about the culture prevalent with people using the language. But your point is well taken. Maybe we can learn from other programming cultures.
> 1/ COBOL run in closed environments. This allows these to be rock solid. (no such thing as a dependency nightmare). You don’t have such a thing as different version of Java on your testing and production environment.
Both Go and Java can do that (yes, without having to install a JVM on the target machine).
COBOL supports "includes" (called copybooks I think) which is poor-man's re-use but at least lets you avoid defining the same common record formats and subroutines individually in every program that needs them.
There was this really great COBOL programmer back in the 1990's who was making piles of money hand over fist, but was overworked and getting really tired of working on Y2K fixes, and becoming extremely worried that civilization was going to collapse due to Y2K bugs. She never wanted to look at another line of COBOL ever again, she was so sick of it.
So she signed up with Alcor, and had herself cryonically frozen in 1999, leaving behind explicit instructions that she was to be revived after civilization had finally put itself back together again.
Finally she woke up, in a clean futuristic hospital room, surrounded by inscrutable machines that go "ping" and strangely dressed doctors with funny accents and weird hairdoos.
She was so happy to be alive that she proclaimed "Thank you so much for bringing me back to life! I am eternally grateful, and in your debt! Is there anything I can do to repay you? And by the way, what year is it?"
One of the doctors smiled at her and said, "Yes, actually. It's the year 9999, and the records indicate that you're a COBOL programmer..."
So, I graduated college this past June and have since started working as a software engineer for a large financial institution. For now, I've been placed on a team of developers where the majority of work is done on mainframes and where most software is written in COBOL.
Today is the last of a 7 week-long "Mainframe Bootcamp" during which I've been introduced to COBOL as well as TSO, JCL, DB2, CICS and MQ. Thus far, I'd say the class has picked up the language fairly quickly, however we've yet to fully grasp the intricacies of development using our company's heavily customized mainframe tools. Generally mundane processes, such as compilation and promotion between environments have been, IMO, rendered tantalizingly complex. It's all really quite tedious and boring. IBM's documentation monopoly hasn't helped, either.
To the point - I question whether COBOL's seemingly polarizing reputation can be somewhat attributed to the environment in which it's usually developed/deployed more-so than the semantic's of the language itself.
My experience with COBOL was on Stratus computers running the VOS operating system. This was a better environment than mainframes, but I'm still ambivalent about the language.
I am bitter (see my other comment in this thread), but this is the first article I've seen in years on COBOL that isn't just Micro Focus astroturfing. +1 on that!
I once had to port COBOL to Java. It presented some interesting problems because of EBCDIC, nibbles,
non IEEE arithmetic, and alien data formats.
A long story short: there are problems where COBOL is better suited than Java.
Were you also moving from a mainframe to a server? I would have thought that Java on a mainframe would handle EBCDIC just fine, but I have never tried it.
the 'mainframe' (a prehistoric Siemens BS2000) no longer really existed as Siemens no longer gave hardware support. Instead, it was virtualised and emulated on a desktop x86.
I worked for one of those companies using COBOL. This strikes me:
> 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.
Why would you want a compiler/language that allows you to shoot yourself in the foot for 1 misplaced character in the source file, without raising an error instead of blindly executing the code?
Like you said, it can change completely the logic of the code so it could be disastrous and go unseen, especially in business transactions?
I know things changed recently. But I would be very surprised if the company I worked updated their COBOL version.
That 72-character limit came about because the most popular IBM punch card reader at the time COBOL was being written could only read 72 of the 80 characters on a card. Once you know that anything after column 72 will be ignored, you can repurpose those columns for other things. At my shop we used them to denote revision numbers. And once practices like that get set, you're pretty much stuck with the older formatting rules.
Yup. When I used RPG400 we'd use the first 4 columns for revision numbers as they were originally reserved on the punched cards but not used on the editor...
It's also solved by modern editors that do syntax highlighting. Both emacs and vim flagged that period as an error when I was working on the example in the article. But sadly the editor I was using at the time did not.
One thing I don’t understand with these very old languages is that I thought the reason they are still around is because of some programs written in the 70s to early 90s are still around and needs to be maintained.
But how complex can these programs be? Surely anything written before 1992-ish can’t involve that much code just because of the limitation of the machines they were designed to run on. What makes it that expensive that no one wants to rewrite them in a modern language?
> But how complex can these programs be? Surely anything written before 1992-ish can’t involve that much code just because of the limitation of the machines they were designed to run on. What makes it that expensive that no one wants to rewrite them in a modern language?
You would be utterly shocked.
I did some COBOL work for a bank.
Most of the new code they write is in C++.
However, COBOL was still a huge part of their stack, and they still had several heavy duty mainframes that it ran on, and maintaining that was part of my job.
For an example of how much COBOL was written back then, and how huge the technical debt to replace it would be:
* The interbank transfer system alone was ~750,000 lines of COBOL.
* It handled around 1.2million transactions every three seconds. That's not capacity, that's real world data.
* They had less than five minutes of downtime in the last twelve months, and that was considered poor.
It's a mammoth task to replace the system, and getting transactions from the old to the new without incurring a huge overhead is nigh impossible. And yes, dropped transactions can mean dropped customers, and big customers.
It's far cheaper to hire and train programmers in COBOL, than to rewrite everything. COBOL and Fortran have millions of lines of code in use, and such frequent use that replacing them may cost more than the lifetime of returns would give.
* They had less than five minutes of downtime in the last twelve months, and that was considered poor.
Yep, that. I did a two-year stint in a major financial network. I guess it's not a lot of time, but while I was there, there was a big outage and it was not on the mainframe side of things- some all modern server farm bought the, er, farm.
From what I can tell, at least in that company, mainframes are still in use because their stability is simply unmatched by anything in the "distributed" world; Cobol is still in use because mainframes are still in use; and nobody dares replace the Cobol code with something else, because the code itself is damn stable, as a result of hundreds of people having worked on it for several decades now- and counting.
In general, Cobol on mainframes is a rock-solid system that doesn't fall down and that nobody wants to disturb.
Cobol programmers are starting to get few nowadays, and finding people that actually want to be trained in it is not that easy. Plus you dont just need programmers, but z/OS engineers, DB2 DBAs, MQ specialists, etc. And that's before you even start talking about the nice cheque you're writing for IBM every month. It does add up.
Most if not all such managers (I always look for explanations in these cases that are not ascribed to an abstract business entity, but to individual people) have no stomach for porting. A typical manager's tenure over an organization that might have the scope to perform the port is shorter than the porting project itself. No manager wants to have such a large, expensive, risky project on their accomplishments list as "started, but not finished", especially if a successor gets to claim all the credit later if it does finish successfully: that successor then becomes direct competition on the corporate ladder climb.
Also, I've yet to see such businesses opt for the safest porting approach. Build a transaction replication system, then a component of the ported system. Inbound transactions are replicated and dispatched to the legacy and the component of the ported system simultaneously. Build scaffolding to monitor key transaction metrics. Compare output and performance results. Let that "bake" for a year or two. Rinse and repeat with the next component (many such ported components can be developed in parallel, etc.), and so on, until the ported system reaches feature parity with the legacy system, then let the completed version "burn in" for 2-3 of the longest periodic process lifecycles. For example, if the the longest periodic process the application supports is once every 7 years, then you burn in for up to 21 years, comparing during the entire duration.
By the time you "throw the switch" to the ported system, you have a very high certainty that it will work just as well if not better than the legacy system. Extremely low-risk, but extremely expensive, and considered extremely impractical. And with how business-critical some of these systems are, pretty much any risk mitigation short of this will get nixed by senior management.
This doesn't even begin to get into other factors, like changing regulatory and business environment as you are porting (so you're porting and modifying for new requirements simultaneously), such a project can easily be targeted for the cutting block for just the cost savings to make someone in Finance look good, internal political issues, developer churn over such a long period, developers on the legacy system withholding key implementation or even business requirements information, that information simply not being available, binary-only parts of legacy, etc.
As i've made clear in my other posts in this thread, i dont believe in rewrites.
I've seen lots of very painful ones though, and never quite finished, nor iso-functional.
However, there are other ways to unplug the mainframe.
I would disagree with the assessment that management is too dysfunctional, it depends. But if they all were like you described, i would be out of work. And it just happens that we turned off a mainframe just 2 weeks ago.
How does your sales team address your customers' concerns that they are trading one vendor lock-in (IBM) with another (your company's)?
From seeing how the risk is assessed in some of my customers, the kind of emulation approach you described (I've seen one for the old HP 3000, and it worked great) sells easily when the legacy vendor is so sclerotic and rapacious that the customer's management is practically pushed out of the relationship, and the economics don't have to completely pencil out to close the sale.
The customer is tied down to a smaller (usually) vendor's emulation, and trust the fidelity of that emulation over time, and furthermore, over new versions. The customer must maintain a skill inventory that isn't "current" (though some people might consider that a plus).
I can think of a couple ways to address those sales objections (lock-in isn't real: can always switch back to legacy vendor if all else fails, no need to revamp staff with crucial business/domain knowledge, etc.). But I'd be really interested in how your sales team deflects them, because I anticipate this legacy software issue will only get worse in our industry over time, and not just on mainframes. I'd like to try to figure out how to bring down the friction of such sales in the future.
>> A typical manager's tenure over an organization that might have the scope to perform the port is shorter than the porting project itself.
I don't think that's the case. In the place I worked (major financial network) the average time people seemed to have ben with the company was 10 years. Especially in big companies, you can expect to see lots of people who go for a long-term career, instead of hopping from job to job (and promotion).
I think the real reason why management doesn't dare to make big changes is that they understand there's a very real risk to cause a significant loss to the company (and lose their job, as a consequence).
Which is why Cobol shops have absolutely mad processes. Where I worked, to make a change to a Cobol program -even if it was just the JCL that would run it- we had to complete a ten-page form, submit it and wait. They basically just don't let you touch the code. You work around it, sorta.
It is still cheaper than porting to the language du jour, like changing plane engines in mid-flight, while ensuring that the new system meets 100% of the existing requirements.
There are alternatives, but i'm biased. See my other comment.
One of the biggest hurdle we have is that the clients dont usually have many tests in place. Testing and validating a full batch night for example (ie 6 hours of intense batch work) is quite complicated.
Well, i know of at least one client that still has the binaries but not the sources of the cobol.
But for the generic case, the mainframe is quite an integrated system, and big clients tend to use a lot of the features at the same time.
Even if you can produce an executable or a library, but you ll still need a transaction manager (CICS/IMS-TM), a database (DB2/IMS), MQ, RACF, Datasets, GDG, REXX/JCL, etc. You need the whole ecosystem.
And all the binaries will expect a DB2, or a MQ listening on the other side, with near-perfect emulation (return codes, db behaviour such as EBCDIC sorting, etc).
Just compiling wont help you much unless you have a very basic use of mostly JCL and batches.
The other problems with porting the code to some other language (like C++):
1. Introduction of errors (both overt and subtle)
2. Fixing of what seem to be issues in the original code that are actually undocumented workarounds (or similar things) to potential bugs (in COBOL or who-knows-what-else-in-the-codebase)
Both are big issues in such a move; software engineers don't often appreciate that much of this old stuff is still around because it WORKS. It has been virtually fully debugged, just through the iteration of time and experience.
So porting can easily introduce bugs that may not be apparent immediately; and because software engineers are always wanting to make thing better, if they are working with the COBOL codebase and see something that they think could be done "better" - that change might actually cause problems down the road, perhaps in ways that aren't recognized immediately, or only in edge cases - things that were worked around decades ago in the COBOL implementation.
> But how complex can these programs be? Surely anything written before 1992-ish can’t involve that much code just because of the limitation of the machines they were designed to run on
An ex-colleague used to work for a major US insurance company, and this is what he told me: They had a bunch of products, and due to the state-by-state nature of US insurance regulation, they had a slightly different version of each product for each of the 50 US states. And then, for every one of those different versions of those products, they had a separate suite of COBOL programs to manage them. And, all these COBOL programs basically did the same things, but all with slight variations due to the different rules of each state's insurance regulators. So they basically had hundreds, maybe even thousands, of separate COBOL programs to maintain, a mess of horribly repetitive code. Their problem with moving off COBOL was not that any of the code was particularly complex, just that there was so much of it, and trying to rewrite it into another language (or, maybe more sensibly, translate it into some sort of business rules engine or insurance policy automation product) would take major effort and run a big risk of getting something wrong in the translation. (He worked there more than 15 years ago, so things at this insurance company might be very different by now.)
This. Suppose you want to rewrite. Your task is to create a new, cleanly written program in a new language that produces the same output as the old, slightly messy COBOL.
It must work identically for all appropriate inputs. There is no documemtation of the code and insufficient documentation of what combinations of inputs must be supported. No one understands the business logic fully. And there are 500,000 lines of copy-paste-modified code to convert. Any screw-up will likely cost more than your annual salary. How do you sell the risk-vs-reward of the rewrite project?
I work on cobol migrations (or anything mainframe more correctly) to x86. I've never seen a rewrite of a real application that actually worked. Some have tried but ended up throwing the towel.
We've taken a different approach, by being binary compatible. Basically we rewrote a CICS/IMS/etc, as well as some z/OS layers.
Depending on the clients, some want to stay in cobol, but others want to modernize, but in a controlled and progressive way.
A complete rewrite is out of the question, but you can try to do it in steps.
Where I work I heard the IT dept literally had to pull developers from retirement to make a change to the payment systems. Sadly pulling people from retirement is an option that the company will not have forever. At one point there will be no other choice but a complete rewrite.
This happened to my grandmother even in the early 90's because of her knowledge and experience with COBOL and Fortran. Also because she knew the software. This was for Shell Oil, I think.
That's interesting. It's a form of adverse selection. The least maintainable and readable languages end up sticking around the longest whereas the clear, concise and readable languages are likely to be replaced regularly with the shiny new thing...
COBOL is readable, in the way that Soviet-era novels were: it all makes sense, it's just tedious. COBOL is as we have seen maintained, so how is it not maintainable? I agree with you that it is not concise.
Because the knowledge required to fix, update or port these programs is almost completely owned by the programmers that developed them, who are in the process of retiring or are unwilling to share knowledge for (justified) fear of losing their job.
Regarding "how complex can these programs be", these programs run core operations for banks and insurance companies, so you can probably imagine the amount of hidden business logic and technical hacks that have stacked up over decades of operation and changes. This will not surface in requirements gathering meetings without A LOT of blood, sweat and tears. The alternative would be to reenginer the company's processes before the building the software to support them, but that would mean a lot of change and that tends to be harder than most software engineering endeavours.
Not only are these programs complex (projects to re-implement them from scratch in J2EE would certainly be measured in years), but they are mission critical and the organization cannot afford to live without them or something 100% equivalent.
I once spent a month completely figuring out a 5000 line C program. You'd be amazed at the complexity a programmer can fit into a small number of lines, particularly when they knew memory mattered, so they needed to make best use of every byte.
>But how complex can these programs be? Surely anything written before 1992-ish can’t involve that much code just because of the limitation of the machines they were designed to run on.
You'd be surprised. The business rules and exactitude of results can be documented in 1000s of pages.
I don’t know about cobol specifically , but I do know about technical debt: Liability and cost of switching. Who will take responsibility for any outages (or much, much worse) if it goes wrong? Who will pay for all the safeguards and processes to prevent that from happening? Easier to keep paying the (predictable, consistent, piece meal) upkeep fee than to spend an unknown chunk of money to take a huge risk for a very low immediate gain.
It’s in a local maximum. Just like all technical debt. And as far as I hear, cobol is used for things that put that risk and liability factor on steroids. I know I wouldn’t touch it without some serious budget to set up massive amounts of redundancy and fail safes.
> What makes it that expensive that no one wants to rewrite them in a modern language?
From a business perspective there may not be much to gain from doing so. If the old software works in a current environment then there often isn't a justification for the cost of rewriting/testing/integrating just to end-up with the same thing in a shiny new language.
I've tried it, so I can say authoritatively: no thank you. Yes, Admiral Hopper should be revered for her work but we have successors now that are superior.
I'm happy not to work with JCL, COBOL, EBCDIC, and mainframes in general. I realize just how much awesomeness in my OSs that I was taking for granted.
Oh my God. I wasted a year of my life on a COBOL project. It is easily the worst language I have ever used.
There is a reason that COBOL is a linguistic dead-end! Functions? Sensible limited variable scope? A decent approach to handling whitespace so that complex, nested branches make sense? COBOL doesn't even have these basics.
Want to declare a variable? You're gonna have to type weird stuff like this: `07 GreatVariableName PIC X(10).`
Oh yeah, and the compiler cost me $3k (great job, Micro Focus), on top of the Solaris machine I had to buy to run it. (This project happened to use `mmap()` via FFI, so it had to run on a Unix machine...)
Maybe I'm a bit bitter, but I will never touch another line of COBOL again.
>>Functions? Sensible limited variable scope? A decent approach to handling whitespace so that complex, nested branches make sense? COBOL doesn't even have these basics.
>>Want to declare a variable? You're gonna have to type weird stuff like this: `07 GreatVariableName PIC X(10).`
I am experiencing this hateful pain and suffering right now. And the previous maintainers hated it too and cut and paste stuff in and out and the files are ~10k lines long and trying to track where a variable has changed, only to find that it depends on another two or more variables, and then trying to track those...
IBM has been trying to fix this for decades. Either through UML/OO interfacing [not kidding], or 4GL language (a slightly more modern language with cobol use case in mind).
I don't despise COBOL, it's mostly a reporting mindset language. Fitted with record file systems you can do some stuff. But if you step outside .. god help you. And if you use X-to-COBOL compilers, then even god cannot help you. Pages and pages of mangled COBOL terms. People show you printouts like war scar tissue on your first day to assert senior status :D
And if you use X-to-COBOL compilers, then even god cannot help you.
Exactly this! I started my professional carreer with COBOL, which I still don't deem to bad for what it was designed.
But we were forced to use Jackson Structured Programing implemented via a pre-compiler (which conveniently ceased to work in regular intervals, since the license expired, but I digress).
You're right! God would have run screaming after one look at the resulting garbage code if we would have the impertinence to ask for help.
I spent a little less time that you doing COBOL and I've never been less productive as a programmer in my life. The language is terrible and the ecosystem is worse. What should take a week to code and deploy took months.
To answer the topic, I've tried COBOL and I hate it. It doesn't deserve respect except in a historical context.
The last time I touched it was in undergrad. I remember a professor in my assembly class was showing us old punch cards. They were made with the fancier machines where it printed the line of code on the bottom of the card. I look at the lines in the stack and was like, "Wait, is this ... is this COBOL?"
I have to agree. Even back in 2001, I found COBOL awful. I recently moved to a new city after having worked Scala jobs for several years. All I can find here is Java work and I dread going back to the god awful word of Spring Boot+MVN+Java after having worked with a considerably better language (usually :-P).
We have better tools today, but the world is left in legacy. So few things have unit/automated tests and without a good crew of engineers, it's very difficult to move things quickly and smoothly to new systems and platforms. Just because COBOL is still in use in so many systems doesn't make it good. It just got popular at the right time, everyone embraced it, and now people who still do it are paid insane amounts of money just to maintain it.
Here's one of my old COBOL programs from University. It was written 15 years ago. I converted from CVS to Git, so the history dates are literally older than github, which is kinda funny:
Readability is relative, of course. It's more readable than assembly language, compared to which COBOL is a win (for its intended use, of course). Compared to GW Basic (or any Basic with line numbers) it's probably about the same, though more verbose. Compared to a modern language, it's less readable and full of bizarre boilerplate.
The question is, if you are not forced by a customer (such as a bank) or by the need to maintain a legacy system, why would you willingly choose COBOL?
Sure, if the money was right. I actually know a bit of COBOL, most of it forgotten. After a while I would move on if they didn’t give me other projects, but I’d even be willing to do it in parallel.
Not sure if I understand you. Isn't "if the money was right" another way of saying "if forced by the customer/platform"? In other words, if the customer told you "pick the language you want" and the platform wasn't a mainframe, why would you choose COBOL?
I never tried it, but a friend of mine who wrote COBOL for a bank was offered a huge bonus for postponing his retirement for a year, and he refused because he was so sick of the language (he still likes programming, by the way).
So I don't hate COBOL, but I'm not particularly interested in trying it either.
I got a nice stock offer to stay with a company doing COBOL for 3 years around Y2K. Of course I took it. By the time the three years had elapsed the stock price had more than doubled. I only eventually got out of COBOL because it was boring.
Years later I was between gigs and interviewed with a company that wanted me to go back to COBOL. I would have, but they lo-balled the salary, like I was going to take a $20K pay cut to go back to COBOL! Ended up staying in the Java world
There have been some very interesting comments made in these comments. Having used COBOL to write communications and networking programs, I found the version we used to be useful in the context of the work being done. I know of people who so hate the language that you could offer them $1,000,000 an hour to work on a project and they would refuse. Others would just as happily take up the offer.
What I do find interesting is the attitude of some who classify COBOL as ancient (etc) and have not yet realised that there are a number of major modern languages that are the spiritual descendants of COBOL. These being ADA, Java, C#, C++ and the rest of their ilk.
They each have a place to play in the computing world, but they each are the wrong language for many purposes. Too oft I find, many programmers know one or two languages and they are the worse off for that. Different languages give different insights into specific problem domains. Every language allows some things to be done easily and other things to be done hard.
Decades ago now, as CompSci undergraduates, we were expected to learn (or at least use) every available language, from Fortran to COBOL, Algol 60 to Lisp, assembler to Simula, Snobol to Pascal, Basic to Algol 68, etc., etc., etc.
These days, undergraduates seem to be taught one or two languages and that's it. It shows up in their later inability to solve certain kinds of problems in a problem space specific way.
I had to program in COBOL for one year when I was in college (in the 70's), I hated it. After that I had to program for one semester in IBM 360 assembly language, which turned out to be a far more interesting and enjoyable programming language.
I give credit where it's due: In 1959 this was a breaktrough; made easy for non-technical people to support business operations using code that was easy to write, easy to understand, massively better than assembly in this regard. Also, record definition and manipulation was an innovation in itself (in an era without RDBMS), not to mention the builtin support for "accounting" decimal arithmetic. It was really "Batteries-Included".
But programming evolved and Cobol did not evolve at the speed of the times. In 1968 (Cobol-68) it was already outdated compared to IBM PL/1 (a big monster of a language, similar but much more powerful).
And in 2017, "Try COBOL"? You mean, try a language where I need to deal with record access as if I were rolling my own DBMS system, with almost no module support, and copious need for copy/paste of code at every file (little chance of code reuse)? Where separation of concerns is almost zero?
No, i think writing in INTERCAL-72, Brainf_ck or LOLCODE would be more fun.
Don't like COBOL but the way it specifies data formats was practical. 9(5) = 5 digits, X(20) = 20 characters, etc. From time to time I catch myself using these while drafting a table or data structure.
I've never written any COBOL, but I have debugged COBOL and determined the source of errors by reading it.
My overall impression is that it's verbose (obviously), but it's also fairly straight-forward and easy to read even if you don't know COBOL.
The most interesting part of it, for me anyway, are the 88-level declarations[0]. Basically it's like a logic test encapsulated in a variable. You can say something like "IF STAFF-MEMBER" where STAFF-MEMBER actually means that some field has a certain value. It makes it easy to understand in some respects, but also adds a layer of obfuscation.
I think COBOL is not a question of hate vs not hate. To hate something you need to consider it, you need to have requirements. If nobody shares an article like this one nobody is actually THINKING about COBOL. If someone starts a new project COBOL is not on the list of possible programming languages to implement it in. If you want to make it more popular don't fight hate, fight ignorance.
But to be honest I'm one of these people who up till now doesn't even consider it a choice. So don't expect too much support or understanding from my side.
I don't think that's a desirable goal. COBOL is not a very good programming language: it's verbose, clunky, cumbersome and outdated. It still exists because of tons of legacy systems and (understandably) conservative businesses like banks. But if you start a new project, please DON'T consider COBOL. To be honest, even my recommendation is irrelevant: you wouldn't start a new COBOL project just as you wouldn't start a new GW Basic project -- it'd be unnatural.
Disclaimer: worked with COBOL for a bank. It wasn't pretty.
It was just an assumption, based on someone writing an article called "Don't hate COBOL until you've tried it". As said, I personally wouldn't even consider it, so there is zero chance to hate it as well.
Yes, it wasn't a criticism of your post! Just a clarification, namely, that I think COBOL evangelism is misplaced, because you're either forced to use it by your customer (often, a bank or similar institution) or you are not, in which case there are plenty of better, modern languages you should use instead. In either case, you don't need someone convincing you to use COBOL. If you're unaware of this language, you don't need it :)
Well... if I was starting a new project that had to run on an MVS mainframe, I probably would in fact consider COBOL. But I'm relatively happy that I probably won't be in that position.
Agreed on all counts. Do note that "making the language more popular" doesn't factor into this: if you need to start a project on an MVS mainframe, you already know about COBOL!
if shipping-method <> 'FX'
move normal-ship-date-yyyymmdd to expected-shipping-date
else
move nextday-ship-date-yyyymmdd to expected-shipping-date.
And not the following?
if shipping-method = 'FX'
move nextday-ship-date-yyyymmdd to expected-shipping-date
else
move normal-ship-date-yyyymmdd to expected-shipping-date.
The latter seems clearer to me, and the line below (regarding the cust-type variable) suggests the syntax would be okay. It would also have the advantage of avoiding the column-length issue described in the post. What am I missing here?
Also efficiency, you want the most often true thing first. Although it is more important in nested if's. Had a colleague write a If else nested 104 levels deep (pre COBOL II so no case structure available). We halved the run time of the program simply by making the four most common conditions the first four.
I'm the author of the article, and to be honest the only reason I did it this way was to make sure the period ended up in column 73. I've presented this in talks about half a dozen times now, and you're the first person ever to notice that. Congrats!
Not having worked with COBOL in about 10 years, the critiques I have of it (from memory) are virtually identical to some modern languages I still have to work with daily.
It's
- Too structured.
- Poor tooling.
- Whitespace sensitivity.
- No first-class functions.
But the article is right - if these same standards were applied to today's languages, things would be a lot louder.
When I wrote the article I didn't have access to code I worked on 2 decades ago, and if I did I couldn't have used it in the article anyway. This was indented to illustrate the problem with problem with column 73, not to handle all possible cases.
Having said that, situations like would come up sometimes. You really did have to decide ahead of time how big field could be. You could leave extra filler bytes in your tables (literally named "filler") but it was still a big hassle to deal with.
It doesn't sound too off to me - I can believe that there are a million legacy COBOL users around and that each writes on average a thousand lines of maintenance code each year. Or maybe fewer users and more lines - COBOL is a notoriously verbose language.
I'm the author of the article, and I linked to the source of those numbers. The numbers seem reasonable to me too for the same reasons dcminter gave. One other reason is COBOL is a language that lends itself to copying and pasting old code instead of writing subroutines, so that leads to a lot of lines of code.
I didn’t like it until I had to program a system 34 in RPG III. Certainly better. When I left the 34, I didn’t like cobol all over again. I could go on at length but I won’t.
One way of solving it would be to just put the code you would otherwise put into a function into another application and call that. Not super pretty, but it works. It's preferable over ending up with a massive program with hundreds of sections.
It’s certainly possible; after all, the GnuCOBOL compiler is written in C. A large part of every COBOL program tends to be simple move and arithmetic statements that seem like they should be easy to port. The difficulty comes with the data declarations. COBOL’s pic statements don’t just define length and whether or not they’re numeric. They also come with complex behaviors that are enforced at run time. For example, anything that’s a pic 9 is stored as a sequence of 0-padded text digits, but you can also do arithmetic on them. They work like a car odometer in that if you add 1 to a variable that’s all 9’s, the result is all 0’s. They also allow you to do arithmetic on currency amounts (like I do in the article) exactly, without having to worry about IEEE floating point round off errors. That’s another reason the banking industry likes COBOL.
If you have an existing COBOL app you can convert it to a web app and develop using a simpler syntax with more features through SystemZ from Zortec Intl. I've worked with them personally and they were super-duper.
COBOL isn't so bad when you use a modern variant that purposefully deals with many of the complaints surrounding it.
No problem and glad to be of [di]service. I was familiar with the URL you posted, and probably should not have commented as a reply to you, but there you have it. :)
COBOL is still pretty efficient for tasks like scanning data on magnetic tapes--not that most of us do that any more. In fact it was pretty good for any problem that involved reading from or writing to storage devices because you could control the data layouts very precisely. It was great on reports for the same reason. I even wrote a simple doc markdown processor in COBOL because the place I worked didn't have usable word processors and we needed something to do pagination and formatting of docs.
I don't miss the verbosity or the lack of modularity but on the other hand COBOL was an effective tool that you could use to solve problems more quickly than other tools available at the time.