#[1]The Cloudflare Blog

  [2]Contact Sales: [3]+1 (888) 274-3482
  [4]The Cloudflare Blog

[5]The Cloudflare Blog

  Thanks for being here, come back soon. Get notified of new posts:

  Subscription confirmed. Thank you for subscribing!

  [6]Product News
  [7]Speed & Reliability
  [8]Security
  [9]Serverless
  [10]Cloudflare Network
  [11]Developers
  [12]Deep Dive
  [13]Life @Cloudflare
  [14][magnifier.svg?v=ed9c53b7ff] [hamburger.svg?v=ed9c53b7ff]
  [15]Product News
  [16]Speed & Reliability
  [17]Security
  [18]Serverless
  [19]Cloudflare Network
  [20]Developers
  [21]Deep Dive
  [22]Life @Cloudflare

Cloudflare Workers Now Support COBOL

  Loading...

  April 16, 2020 12:00PM
    * [23]John Graham-Cumming
      [24]John Graham-Cumming

  Recently, COBOL has been in the news as the State of New Jersey has
  [25]asked for help with a COBOL-based system for unemployment claims.
  The system has come under heavy load because of the societal effects of
  the SARS-CoV-2 virus. This appears to have prompted IBM to offer
  [26]free online COBOL training.
  [report-cropped.png]

  As old as COBOL is (60 years old this month), it is still heavily used
  in information management systems and pretty much anywhere there’s an
  IBM mainframe around. Three years ago Thomson Reuters [27]reported that
  COBOL is used in 43% of banking systems, is behind 80% of in-person
  financial transactions and 95% of times an ATM card is used. They also
  reported 100s of billions of lines of running COBOL.

  COBOL is often a source of amusement for programmers because it is seen
  as old, verbose, clunky, and difficult to maintain. And it’s often the
  case that people making the jokes have never actually written any
  COBOL. We plan to give them a chance: COBOL can now be used to write
  code for Cloudflare’s serverless platform Workers.

  Here’s a simple “Hello, World!” program written in COBOL and accessible
  at [28]https://hello-world.cobol.workers.dev/. It doesn’t do much--it
  just outputs “Hello, World!”--but it does it using COBOL.
       IDENTIFICATION DIVISION.
       PROGRAM-ID. HELLO-WORLD.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 HTTP_OK   PIC X(4)  VALUE "200".
       01 OUTPUT_TEXT PIC X(14) VALUE "Hello, World!".
       PROCEDURE DIVISION.
           CALL "set_http_status" USING HTTP_OK.
           CALL "append_http_body" USING OUTPUT_TEXT.
       STOP RUN.

  If you’ve never seen a COBOL program before, it might look very odd.
  The language emerged in 1960 from the work of a committee designing a
  language for business (COBOL = COmmon Business Oriented Language) and
  was intended to be easy to read and understand (hence the verbose
  syntax). It was partly based on an early language called [29]FLOW-MATIC
  created by Grace Hopper.

IDENTIFICATION DIVISION.

  To put COBOL in context: FORTRAN arrived in 1957, LISP and ALGOL in
  1958, APL in 1962 and BASIC in 1964. The C language didn’t arrive on
  scene until 1972. The late 1950s and early 1960s saw a huge amount of
  work on programming languages, some coming from industry (such as
  FORTRAN and COBOL) and others from academia (such as LISP and ALGOL).

  COBOL is a compiled language and can easily be compiled to WebAssembly
  and run on Cloudflare Workers. If you want to get started with COBOL,
  the [30]GNUCobol project is a good place to begin.

  Here’s a program that waits for you to press ENTER and then adds up the
  numbers 1 to 1000 and outputs the result:
      IDENTIFICATION DIVISION.
      PROGRAM-ID. ADD.
      ENVIRONMENT DIVISION.
      DATA DIVISION.
      WORKING-STORAGE SECTION.
      77 IDX  PICTURE 9999.
      77 SUMX PICTURE 999999.
      77 X    PICTURE X.
      PROCEDURE DIVISION.
      BEGIN.
          ACCEPT X.
          MOVE ZERO TO IDX.
          MOVE ZERO TO SUMX.
          PERFORM ADD-PAR UNTIL IDX = 1001.
          DISPLAY SUMX.
          STOP RUN.
      ADD-PAR.
          COMPUTE SUMX = SUMX + IDX.
          ADD 1 TO IDX.

  You can compile it and run it using GNUCobol like this (I put this in a
  file called terminator.cob)
$ cobc -x terminator.cob
$ ./terminator
500500
$

  cobc compiles the COBOL program to an executable file. It can also
  output a C file containing C code to implement the COBOL program:

  $ cobc -C -o terminator.c -x terminator.cob

  This .c file can then be compiled to WebAssembly. I’ve done that and
  placed this program (with small modifications to make it output via
  HTTP, as in the Hello, World! program above) at
  [31]https://terminator.cobol.workers.dev/. Note that the online version
  doesn’t wait for you to press ENTER, it just does the calculation and
  gives you the answer.

DATA DIVISION.

  You might be wondering why I called this terminator.cob. That’s because
  this is part of the code that appears in The Terminator, James
  Cameron’s 1984 film. The film features a ton of code from the Apple ][
  and a little snippet of COBOL (see the screenshot from the film below).
  [image2-14.png]

  The screenshot shows the view from one of the HK-Aerial hunter-killer
  VTOL craft used by Skynet to try to wipe out the remnants of humanity.
  Using COBOL.

  You can learn all about that in this YouTube video I produced:

  IFRAME: [32]https://www.youtube.com/embed/YRnnjoiSV-U?feature=oembed

  For those of you of the nerdy persuasion, here’s the original code as
  it appeared in the [33]May 1984 edition of “73 Magazine” and was copied
  to look cool on screen in The Terminator.
  [dr-digital-cropped.png]

  If you want to scale your own COBOL-implemented Skynet, it only takes a
  few steps to convert COBOL to WebAssembly and have it run in over 200
  cities worldwide on Cloudflare’s network.

PROCEDURE DIVISION.

  Here’s how you can take your COBOL program and turn it into a Worker.

  There are multiple compiler implementations of the COBOL language and a
  few of them are proprietary. We decided to use GnuCOBOL (formerly
  OpenCOBOL) because it's free software.

  Given that Cloudflare Workers supports WebAssembly, it sounded quite
  straightforward: GnuCOBOL can compile COBOL to C and Emscripten
  compiles C/C++ to WebAssembly. However, we need to make sure that our
  WebAssembly binary is as small and fast as possible to maximize the
  time for user-code to run instead of COBOL's runtime.

  GnuCOBOL has a runtime library called libcob, which implements COBOL's
  runtime semantics, using GMP (GNU Multiple Precision Arithmetic
  Library) for arithmetic. After we compiled both these libraries to
  WebAssembly and linked against our compiled COBOL program, we threw the
  WebAssembly binary in a Cloudflare Worker.

  It was too big and it hit the CPU limit (you can find [34]Cloudflare
  Worker’s limits here), so it was time to optimize.

  GMP turns out to be a big library, but luckily for us someone made an
  optimized version for JavaScript
  ([35]https://github.com/kripken/gmp.js), which was much smaller and
  reduced the WebAssembly instantiation time. As a side note, it's often
  the case that functions implemented in C could be removed in favour of
  a JavaScript implementation already existing on the web platform. But
  for this project we didn’t want to rewrite GMP.

  While Emscripten can emulate a file system with all its syscalls, it
  didn't seem necessary in a Cloudflare Worker. We patched GnuCOBOL to
  remove the support for local user configuration and other small things,
  allowing us to remove the emulated file system.

  The size of our Wasm binary is relatively small compared to other
  languages. For example, around 230KB with optimization enabled for the
  Game of Life later in this blog post.

  Now that we have a COBOL program running in a Cloudflare Worker, we
  still need a way to generate an HTTP response.

  The HTTP response generation and manipulation is written in JavaScript
  (for now... some changes to WebAssembly are currently being discussed
  that would allow a better integration). Emscripten imports these
  functions and makes them available in C, and finally we link all the C
  code with our COBOL program. COBOL already has good interoperability
  with C code.

  As an example, we implemented the rock-paper-scissors game
  ([36]https://github.com/cloudflare/cobol-worker/blob/master/src/worker.
  cob). See the full source
  ([37]https://github.com/cloudflare/cobol-worker).

  IFRAME: [38]https://cobol.speedcf.com/

  Our work can be used by anyone wanting to compile COBOL to WebAssembly;
  the toolchain we used is available on GitHub
  ([39]https://github.com/cloudflare/cobaul) and is free to use.

  To deploy your own COBOL Worker, you can run the following commands.
  Make sure that you have wrangler installed on your machine
  (https://github.com/cloudflare/wrangler).

  wrangler generate cobol-worker
  [40]https://github.com/cloudflare/cobol-worker-template

  It will generate a cobol-worker directory containing the Worker. Follow
  the instructions in your terminal to configure your Cloudflare account
  with wrangler.

  Your worker is ready to go; enter npm run deploy and once deployed the
  URL will be displayed in the console.

STOP RUN.

  I am very grateful to Sven Sauleau for doing the work to make it easy
  to port a COBOL program into a Workers file and for writing the
  PROCEDURE DIVISION section above and to Dane Knecht for suggesting
  Conway’s Game of Life.

  Cloudflare Workers with WebAssembly is an easy-to-use serverless
  platform that’s fast and cheap and scalable. It supports a wide variety
  of languages--including COBOL (and C, C++, Rust, Go, JavaScript, etc.).
  Give it a try today.

AFTERWORD

  We learnt the other day of the death of [41]John Conway who is well
  known for [42]Conway’s Game of Life. In tribute to Conway, XKCD
  [43]dedicated a cartoon:

  I decided to implement the Game of Life in COBOL and reproduce the
  cartoon.

  IFRAME: [44]https://game-of-life.cobol.workers.dev/

  Here’s the code:
IDENTIFICATION DIVISION.
      PROGRAM-ID. worker.
      DATA DIVISION.
      WORKING-STORAGE SECTION.
      01 PARAM-NAME PIC X(7).
      01 PARAM-VALUE PIC 9(10).
      01 PARAM-OUTPUT PIC X(10).
      01 PARAM PIC 9(10) BINARY.
      01 PARAM-COUNTER PIC 9(2) VALUE 0.
      01 DREW PIC 9 VALUE 0.
      01 TOTAL-ROWS PIC 9(2) VALUE 20.
      01 TOTAL-COLUMNS PIC 9(2) VALUE 15.
      01 ROW-COUNTER PIC 9(2) VALUE 0.
      01 COLUMN-COUNTER PIC 9(2) VALUE 0.
      01 OLD-WORLD PIC X(300).
      01 NEW-WORLD PIC X(300).
      01 CELL PIC X(1) VALUE "0".
      01 X PIC 9(2) VALUE 0.
      01 Y PIC 9(2) VALUE 0.
      01 POS PIC 9(3).
      01 ROW-OFFSET PIC S9.
      01 COLUMN-OFFSET PIC S9.
      01 NEIGHBORS PIC 9 VALUE 0.
      PROCEDURE DIVISION.
          CALL "get_http_form" USING "state" RETURNING PARAM.
          IF PARAM = 1 THEN
             PERFORM VARYING PARAM-COUNTER FROM 1 BY 1 UNTIL PARAM-COUNTER > 30
                STRING "state" PARAM-COUNTER INTO PARAM-NAME
                CALL "get_http_form" USING PARAM-NAME RETURNING PARAM-VALUE
                COMPUTE POS = (PARAM-COUNTER - 1) * 10 + 1
                MOVE PARAM-VALUE TO NEW-WORLD(POS:10)
             END-PERFORM
         ELSE
           MOVE "00000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000011100000000000010100000000000010
10000000000000100000000000101110000000000010101000000000000100100000000001010000
000000001010000000000000000000000000000000000000000000000000000000000000000000"
TO NEW-WORLD.
          PERFORM PRINT-WORLD.
          MOVE NEW-WORLD TO OLD-WORLD.
          PERFORM VARYING ROW-COUNTER FROM 1 BY 1 UNTIL ROW-COUNTER > TOTAL-ROW
S
              PERFORM ITERATE-CELL VARYING COLUMN-COUNTER FROM 1 BY 1 UNTIL COL
UMN-COUNTER > TOTAL-COLUMNS
          END-PERFORM.
          PERFORM PRINT-FORM.
          STOP RUN.
      ITERATE-CELL.
          PERFORM COUNT-NEIGHBORS.
          COMPUTE POS = (ROW-COUNTER - 1) * TOTAL-COLUMNS + COLUMN-COUNTER.
          MOVE OLD-WORLD(POS:1) TO CELL.
          IF CELL = "1" AND NEIGHBORS < 2 THEN
              MOVE "0" TO NEW-WORLD(POS:1).
          IF CELL = "1" AND (NEIGHBORS = 2 OR NEIGHBORS = 3) THEN
              MOVE "1" TO NEW-WORLD(POS:1).
          IF CELL = "1" AND NEIGHBORS > 3 THEN
              MOVE "0" TO NEW-WORLD(POS:1).
          IF CELL = "0" AND NEIGHBORS = 3 THEN
              MOVE "1" TO NEW-WORLD(POS:1).
      COUNT-NEIGHBORS.
          MOVE 0 TO NEIGHBORS.
          PERFORM COUNT-NEIGHBOR
              VARYING ROW-OFFSET FROM -1 BY 1 UNTIL ROW-OFFSET > 1
                 AFTER COLUMN-OFFSET FROM -1 BY 1 UNTIL COLUMN-OFFSET > 1.
      COUNT-NEIGHBOR.
          IF ROW-OFFSET <> 0 OR COLUMN-OFFSET <> 0 THEN
              COMPUTE Y = ROW-COUNTER + ROW-OFFSET
              COMPUTE X = COLUMN-COUNTER + COLUMN-OFFSET
              IF X >= 1 AND X <= TOTAL-ROWS AND Y >= 1 AND Y <= TOTAL-COLUMNS T
HEN
                  COMPUTE POS = (Y - 1) * TOTAL-COLUMNS + X
                  MOVE OLD-WORLD(POS:1) TO CELL
                  IF CELL = "1" THEN
                     COMPUTE NEIGHBORS = NEIGHBORS + 1.
      PRINT-FORM.
          CALL "append_http_body" USING "<form name=frm1 method=POST><input typ
e=hidden name=state value=".
          CALL "append_http_body" USING DREW.
          CALL "append_http_body" USING ">".
          PERFORM VARYING PARAM-COUNTER FROM 1 BY 1 UNTIL PARAM-COUNTER > 30
              CALL "append_http_body" USING "<input type=hidden name=state"
              CALL "append_http_body" USING PARAM-COUNTER
              CALL "append_http_body" USING " value="
              COMPUTE POS = (PARAM-COUNTER - 1) * 10 + 1
              MOVE NEW-WORLD(POS:10) TO PARAM-OUTPUT
              CALL "append_http_body" USING PARAM-OUTPUT
              CALL "append_http_body" USING ">"
          END-PERFORM
          CALL "append_http_body" USING "</form>".
      PRINT-WORLD.
          MOVE 0 TO DREW.
          CALL "set_http_status" USING "200".
          CALL "append_http_body" USING "<html><body onload='setTimeout(functio
n() { document.frm1.submit() }, 1000)'>"
          CALL "append_http_body" USING "<style>table { background:-color: whit
e; } td { width: 10px; height: 10px}</style>".
          CALL "append_http_body" USING "<table>".
          PERFORM PRINT-ROW VARYING ROW-COUNTER FROM 3 BY 1 UNTIL ROW-COUNTER >
= TOTAL-ROWS - 1.
          CALL "append_http_body" USING "</table></body></html>".
      PRINT-ROW.
          CALL "append_http_body" USING "<tr>".
          PERFORM PRINT-CELL VARYING COLUMN-COUNTER FROM 3 BY 1 UNTIL COLUMN-CO
UNTER >= TOTAL-COLUMNS - 1.
          CALL "append_http_body" USING "</tr>".
      PRINT-CELL.
          COMPUTE POS = (ROW-COUNTER - 1) * TOTAL-COLUMNS + COLUMN-COUNTER.
          MOVE NEW-WORLD(POS:1) TO CELL.
          IF CELL = "1" THEN
              MOVE 1 TO DREW
              CALL "append_http_body" USING "<td bgcolor=blue></td>".
          IF CELL = "0" THEN
              CALL "append_http_body" USING "<td></td>".

  If you want to run your own simulation you can do an HTTP POST with 30
  parameters that when concatenated form the layout of the 15x20 world
  simulated in COBOL.

  If you want to install this yourself, take the following steps:
   1. Sign up for Cloudflare
   2. Sign up for a [45]workers.dev subdomain. I've already grabbed
      cobol.workers.dev, but imagine you’ve managed to grab
      my-cool-name.workers.dev
   3. Install [46]wrangler, Cloudflare’s CLI for deploying Workers
   4. Create a new COBOL Worker using the template
wrangler generate cobol-worker https://github.com/cloudflare/cobol-worker-templa
te

   5. Configure wrangler.toml to point to your account and set a name for
      this project, let’s say my-first-cobol.
   6. Grab the files src/index.js and src/worker.cob from my repo here:
      [47]https://github.com/jgrahamc/game-of-life and replace them in
      the cobol-worker.
   7. npm run deploy
   8. The COBOL Worker will be running at
      https://my-first-cobol.my-cool-name.workers.dev/

  [48]COBOL [49]Cloudflare Workers

  Related Posts

    * Sales
    * [50]Enterprise Sales
    * [51]Become a Partner

  Contact Sales:

  [52]+1 (888) 99 FLARE
  [53]+1 650 319 8930
    * Getting Started
    * [54]Pricing
    * [55]Case Studies
    * [56]White Papers
    * [57]Webinars
    * [58]Learning Center

    * Community
    * [59]Community Hub
    * [60]Blog
    * [61]Project Galileo
    * [62]Athenian Project

    * Developers
    * [63]Developer Hub
    * [64]Technical Resources
    * [65]Cloudflare Workers
    * [66]Integrations

    * Support
    * [67]Support
    * [68]Cloudflare Status
    * [69]Compliance
    * [70]GDPR

    * Company
    * [71]About Cloudflare
    * [72]Our Team
    * [73]Press
    * [74]Analysts
    * [75]Careers
    * [76]Internet Summit
    * [77]Logo
    * [78]Network Map

  [79][facebook.svg] [80][twitter.svg] [81][linkedin.svg]
  [82][youtube.svg] [83][instagram.svg]
  © 2020 Cloudflare, Inc. | [84]Privacy Policy | [85]Terms of Use |
  [86]Trust & Safety | [87]Trademark

  Please enable JavaScript to view the [88]comments powered by Disqus.
  [89]comments powered by Disqus

  IFRAME: [90]https://www.googletagmanager.com/ns.html?id=GTM-PKQFGQB

References

  1. https://blog.cloudflare.com/rss/
  2. https://www.cloudflare.com/plans/enterprise/contact/
  3. tel:+18889935273
  4. https://www.cloudflare.com/
  5. https://blog.cloudflare.com/
  6. https://blog.cloudflare.com/tag/product-news/
  7. https://blog.cloudflare.com/tag/speed-and-reliability/
  8. https://blog.cloudflare.com/tag/security/
  9. https://blog.cloudflare.com/tag/serverless/
 10. https://blog.cloudflare.com/tag/cloudflare-network/
 11. https://blog.cloudflare.com/tag/developers/
 12. https://blog.cloudflare.com/tag/deep-dive/
 13. https://blog.cloudflare.com/tag/life-at-cloudflare/
 14. https://blog.cloudflare.com/search/
 15. https://blog.cloudflare.com/tag/product-news/
 16. https://blog.cloudflare.com/tag/speed-and-reliability/
 17. https://blog.cloudflare.com/tag/security/
 18. https://blog.cloudflare.com/tag/serverless/
 19. https://blog.cloudflare.com/tag/cloudflare-network/
 20. https://blog.cloudflare.com/tag/developers/
 21. https://blog.cloudflare.com/tag/deep-dive/
 22. https://blog.cloudflare.com/tag/life-at-cloudflare/
 23. https://blog.cloudflare.com/author/john-graham-cumming/
 24. https://blog.cloudflare.com/author/john-graham-cumming
 25. https://slate.com/technology/2020/04/new-jersey-unemployment-cobol-coronavirus.html
 26. https://newsroom.ibm.com/2020-04-09-IBM-and-Open-Mainframe-Project-Mobilize-to-Connect-States-with-COBOL-Skills
 27. http://fingfx.thomsonreuters.com/gfx/rngs/USA-BANKS-COBOL/010040KH18J/index.html
 28. https://hello-world.cobol.workers.dev/
 29. https://en.wikipedia.org/wiki/FLOW-MATIC
 30. https://ftp.gnu.org/gnu/gnucobol/
 31. https://terminator.cobol.workers.dev/
 32. https://www.youtube.com/embed/YRnnjoiSV-U?feature=oembed
 33. https://archive.org/details/73-magazine-1984-05/mode/2up
 34. https://developers.cloudflare.com/workers/about/limits/#cpu-execution-time-limit
 35. https://github.com/kripken/gmp.js
 36. https://github.com/cloudflare/cobol-worker/blob/master/src/worker.cob
 37. https://github.com/cloudflare/cobol-worker
 38. https://cobol.speedcf.com/
 39. https://github.com/cloudflare/cobaul
 40. https://github.com/cloudflare/cobol-worker-template
 41. https://en.wikipedia.org/wiki/John_Horton_Conway
 42. https://en.wikipedia.org/wiki/Conway's_Game_of_Life
 43. https://xkcd.com/2293/
 44. https://game-of-life.cobol.workers.dev/
 45. https://workers.dev/
 46. https://github.com/cloudflare/wrangler
 47. https://github.com/jgrahamc/game-of-life
 48. https://blog.cloudflare.com/404/
 49. https://blog.cloudflare.com/tag/workers/
 50. https://cloudflare.com/plans/enterprise/contact/
 51. https://cloudflare.com/partners/
 52. tel:+18889935273
 53. tel:+16503198930
 54. https://cloudflare.com/plans/
 55. https://cloudflare.com/case-studies/
 56. https://cloudflare.com/resources/
 57. https://cloudflare.com/webinars/
 58. https://cloudflare.com/learning/
 59. https://community.cloudflare.com/
 60. https://blog.cloudflare.com/
 61. https://cloudflare.com/galileo/
 62. https://cloudflare.com/athenian/
 63. https://developers.cloudflare.com/
 64. https://cloudflare.com/technical-resources/
 65. https://cloudflare.com/products/cloudflare-workers/
 66. https://cloudflare.com/integrations/
 67. https://support.cloudflare.com/
 68. https://www.cloudflarestatus.com/
 69. https://cloudflare.com/compliance/
 70. https://cloudflare.com/gdpr/introduction/
 71. https://cloudflare.com/about-overview/
 72. https://cloudflare.com/people/
 73. https://cloudflare.com/press/
 74. https://cloudflare.com/analysts/
 75. https://cloudflare.com/careers/
 76. https://cloudflare.com/internetsummit/
 77. https://cloudflare.com/logo/
 78. https://cloudflare.com/network/
 79. https://www.facebook.com/Cloudflare/
 80. https://twitter.com/Cloudflare
 81. https://www.linkedin.com/company/cloudflare-inc-
 82. https://www.youtube.com/cloudflare
 83. https://www.instagram.com/cloudflare
 84. https://cloudflare.com/privacypolicy/
 85. https://cloudflare.com/website-terms/
 86. https://cloudflare.com/abuse/
 87. https://cloudflare.com/trademark/
 88. http://disqus.com/?ref_noscript
 89. http://disqus.com/
 90. https://www.googletagmanager.com/ns.html?id=GTM-PKQFGQB