COBOL Quick Guide



  • A "quick guide" to COBOL, which someone apparently wrote in 2014...

    Points of note:

    • COBOL is disgustingly odious. The thing which is worse is that the example code isn't even good COBOL, it's full of obvious bugs and errors (aside from being written in COBOL).
    IDENTIFICATION DIVISION.
    PROGRAM-ID. HELLO.
    ENVIRONMENT DIVISION.
    INPUT-OUTPUT SECTION.
    FILE-CONTROL.
    SELECT FILEN ASSIGN TO INPUT.
           ORGANIZATION IS SEQUENTIAL.
           ACCESS IS SEQUENTIAL.
    DATA DIVISION.
    FILE SECTION.
    FD FILEN
    01 NAME PIC A(25).
    WORKING-STORAGE SECTION.
    01 WS-STUDENT PIC A(30).
    01 WS-ID PIC 9(5).
    LOCAL-STORAGE SECTION.
    01 LS-CLASS PIC 9(3).
    LINKAGE SECTION.
    01 LS-ID PIC 9(5).
    PROCEDURE DIVISION.
    DISPLAY 'Executing COBOL program using JCL'.
    STOP RUN.
    
    • The JCL to execute the above COBOL program is as follows:
    //SAMPLE JOB(TESTJCL,XXXXXX),CLASS=A,MSGCLASS=C
    //STEP1 EXEC PGM=HELLO
    //INPUT DD DSN=ABC.EFG.XYZ,DISP=SHR
    
    • Also it has "paragraphs" and GO TO as the primary way to structure a program:
    IDENTIFICATION DIVISION.
    PROGRAM-ID. HELLO.
    DATA DIVISION.
    WORKING-STORAGE SECTION.
    01 WS-A PIC 9 VALUE 2.
    PROCEDURE DIVISION.
    A-PARA.
    DISPLAY 'IN A-PARA'
    GO TO B-PARA.
    B-PARA.
    DISPLAY 'IN B-PARA '.
    GO TO C-PARA D-PARA DEPENDING ON WS-A.
    C-PARA.
    DISPLAY 'IN C-PARA '.
    D-PARA.
    DISPLAY 'IN D-PARA '.
    STOP RUN.
    
    • It gets much much worse, and this is all just from the first page:
    The source program of COBOL must be written in a format acceptable to the compilers. COBOL programs are written on COBOL coding sheets. There are 80 characters position on each line of a coding sheet.
    (It then goes on to list a table enumerating the sematics of each character column position...)
    • Actually the worst thing about this is that I read the whole thing...


  • @TAR said:

    SELECT FILEN ASSIGN TO INPUT.

    LINQ TO COBOL?



  • WHY ALL THIS SHOUTING?

    BODY IS INVALID?!



  • @TAR said:

    @BEN_LUBAR said:
    @TAR said:
    SELECT FILEN ASSIGN TO INPUT.

    LINQ TO COBOL?

    WHY ALL THIS SHOUTING?

    BODY IS INVALID?!

    I TRIED TO ANSWER BUT



  • Nothing kills discourse more than disabled interactions.



  • I started getting into the tutorial. Then I realized "WTF am I doing" and shut it off.

    BTW their online cobol fiddle crashes when you try to run the code. I guess the interest spike from TDWTF was too much.



  • I have not a single clue of what those snippets do... good.



  • That makes Fortran 77 code look sane.



  • WORKING-STORAGE SECTION.
    01 WS-STUDENT PIC A(30).
    01 WS-ID PIC 9(5).
    

    Declare two global variables (because there are no local variables):

    WS-STUDENT is a 30-character string accepting alphebetic characters (PIC A(30)).
    WS-ID is a 5 digit decimal number (PIC 9(5)).

    You can also have an alphanumeric variable of n characters via PIC X(n) and there's a couple of other variable "types" as well (but they're all horrible).

    These globals are both at level 01 (you really don't want to know...)


  • BINNED

    Many of these ancient languages are written to ease the job of the parser, not programmer. If you think in that light their choice of identifiers and syntax becomes obvious. It looks like each line in the code could be parsed with simple regular expressions, limit to all-caps, and it requires very little memory too. COBOL looks like a fancy assembly language.



  • @tar said:

    Declare two global variables (because there are no local variables):

    I recall an esoteric language that had more global variables than COBOL.



  • @tar said:

    Also it has "paragraphs" and GO TO as the primary way to structure a program:

    Where the hell did you find this example? This practice went out with button shoes. Best practice is to use PERFORM THRU with EXIT paragraphs. Summary of some rules at our shop:

    1. Every paragraph must have a corresponding EXIT paragraph.
    2. PERFORM THRU is mandatory and may perform one paragraph through its corresponding EXIT.
    3. GO TO DEPENDING ON is prohibited, as well as (shudder) ALTER (using the latter might well be a career decision).
    4. GO TO is permitted only to the EXIT paragraph of the paragraph in which it is contained, which makes it functionally equivalent to C/C++/C# "return" statement.
    5. Use of structured blocks, with indentation, is mandatory.
    6. Use of period except at the end of a paragraph is prohibited. Periods are no longer needed to separate verbs; the verb reserved-word identifies the start of the next clause.
    7. NEXT SENTENCE is prohibited.
    8. The program begins with a main paragraph that ends with the STOP RUN. In normal operation, the program may end only by executing the STOP RUN at the end of that first paragraph.
     IDENTIFICATION DIVISION. 
     PROGRAM-ID. HELLO.
     DATA DIVISION.
     WORKING-STORAGE SECTION.
     01 WS-A PIC 9 VALUE 2.
     PROCEDURE DIVISION.
     A-PARA.
         DISPLAY 'IN A-PARA'
         PERFORM B-PARA THRU B-PARA-EXIT
         STOP RUN
         .
     A-PARA-EXIT.
         EXIT.
    
     B-PARA.
         DISPLAY 'IN B-PARA '
         IF WS-A = 1
             PERFORM C-PARA THRU C-PARA-EXIT
         ELSE
             PERFORM D-PARA THRU D-PARA-EXIT
         END-IF
         EVALUATE WS-A
            WHEN 1
               PERFORM C-PARA THRU C-PARA-EXIT
            WHEN 2
               PERFORM D-PARA THRU D-PARA-EXIT
            WHEN OTHER
               PERFORM D-PARA THRU D-PARA-EXIT
          END-EVALUATE
          .
     B-PARA-EXIT.
         EXIT.
    
     C-PARA.
         DISPLAY 'IN C-PARA '
         .
     C-PARA-EXIT
         EXIT.
    
     D-PARA.
         DISPLAY 'IN D-PARA '
         .
     D-PARA-EXIT.
         EXIT.
    

    No GO TO at all. I demonstrated both block format IF and the EVALUATE statement, which is similar to SWITCH or CASE (actually the best designed such statement in any language IMHO).

    The language generally sucks, I agree, and I regard it as a dead language (even though it is my mainstay). But the people using the examples similar to that presented in the intro, are getting them from stone age archaeological digs.


  • Discourse touched me in a no-no place

    @dse said:

    Many of these ancient languages are written to ease the job of the parser, not programmer.

    Any language that was pre-Algol (and a number that were later) was written without the concept of a proper grammar. Algol was a hugely important language; while hardly anyone uses it now, its descendants have taken over almost completely.

    @CoyneTheDup said:

    No GO TO at all. I demonstrated both block format IF and the EVALUATE statement, which is similar to SWITCH or CASE (actually the best designed such statement in any language IMHO).

    How are while loops done? (I bet it won't be by recursion… ;))



  • COBOL was developed along time ago -- sometime around the K-Pg boundary. Way back then systems used 6 bit codes. That meant ten digits, a couple of control characters, a little bit of punctuation, and one alphabet. As every good monotheist knows, you can't spell GOD in an all lower case alphabet.



  • @dkf said:

    How are while loops done? (I bet it won't be by recursion… )

    (A side note to @Unixwolf: Modern COBOL is case-insensitive. One of the stupid-rules I have do deal with is my organization mandates upper case statements. I'll do pendantic lower case in these examples.)

    Looping is not by recursion, no. The equivalent of a while loop is a variation of the perform statement (except that it is performed until-true instead of until-false):

         move 1 to ws-a
         move 0 to ws-t
         perform until ws-a > 20
            compute ws-t = ws-t + ws-a
            display ' Cumulative sum of 1 to ' ws-a ' is ' ws-t '.'
            compute ws-a = ws-a + 1
        end-perform
    

    (Well, one thing leaps out right away: The COBOL highlighting seems to be unaware that modern COBOL is case insensitive. Dizzycourse!!!)

    The perform can also be executed as the do - until form by changing when the test is performed:

         move 1 to ws-a
         move 0 to ws-t
         perform with test after until ws-a > 20
            compute ws-t = ws-t + ws-a
            display ' Cumulative sum of 1 to ' ws-a ' is ' ws-t '.'
            compute ws-a = ws-a + 1
        end-perform
    

    Normally, the test is executed before executing the PERFORM body, as in while; the with test after clause causes the body to always execute once, even if the test is initially true. (It's uncommon to actually need this clause.)

    The varying clause allows a variable to be incremented similar to for:

         move 0 to ws-t
         perform varying ws-a from 1 by 1 until ws-a > 20
            compute ws-t = ws-t + ws-a
            display ' Cumulative sum of 1 to ' ws-a ' is ' ws-t '.'
         end-perform
    

    There are two ways to execute a sub-paragraph as a loop. This is the block form (with the perform - thru in the body of the looping perform):

         move 0 to ws-t
         perform varying ws-a from 1 by 1 until ws-a > 20
            perform b-para thru b-para-exit
         end-perform
    

    Then there is the option to loop a perform - thru statement form (which I avoid myself, since it tends to hide the varying - until (note the absence of the closing end-perform), In this example, the entire perform - thru - varying - until is one statement:

         move 0 to ws-t
         perform b-para thru b-para-exit
            varying ws-a from 1 by 1 until ws-a > 20
    


  • @CoyneTheDup said:

    One of the stupid-rules I have do deal with is my organization mandates upper case statementsCOBOL.

    FTFY



  • @CoyneTheDup said:

    (Well, one thing leaps out right away: The COBOL highlighting seems to be unaware that modern COBOL is case insensitive. Dizzycourse!!!)

    bug reports go here https://github.com/isagalaev/highlight.js/issues



  • Unfortunately no time to explain, but I'll second @CoyneTheDup 's (semi)defense of the Ancient Tongue.



  • @CoyneTheDup said:

    COBOL highlighting

    It's not doing COBOL highlighting. As @riking points out, it's not Discourse doing the highlighting, but highlight.js, which doesn't have a COBOL option.

    The highlighting you're getting is bash.



  • @ChaosTheEternal said:

    It's not doing COBOL highlighting. As @riking points out, it's not Discourse doing the highlighting, but highlight.js, which doesn't have a COBOL option.

    [whisper] Here's a little secret: I knew that, but it's more fun to blame Dizzycourse. 😇 [/whisper]



  • @ChaosTheEternal said:

    The highlighting you're getting is bash.

    In the OP, I told it I was writing Go, which made it highlight COBOL in a semi-non-awful way,


  • kills Dumbledore

    Col, we've found something Go is non-awful at


  • I survived the hour long Uno hand

    GOBOL? <invalid my ass



  • @tar said:

    In the OP, I told it I was writing Go, which made it highlight COBOL in a semi-non-awful way,

    @Jaloopa said:

    Cool, we've found something Go is semi-non-awful at

    FTFY


  • :belt_onion:

    Requisite Paging @Ben_Lubar


  • ♿ (Parody)

    @tar said:

    Also it has "paragraphs" and GO TO as the primary way to structure a program:

    Well, yes. Paragraphs and sentences just make sense. See, just like I'm communicating to you; now imagine if I could simply communicate my desires to a computer in the same manner. As a subject matter expert, why should I need to learn the curly braces and programming jargon that you programmers use, like functions and subroutines. If I can write in plain, simple English, then I can program.

    Wait, I forgot, are we talking about Cucumber?



  • @apapadimoulis said:

    Wait, I forgot, are we talking about Cucumber?

    [code]
    The Infamous Hello World Program.

    Romeo, a young man with a remarkable patience.
    Juliet, a likewise young woman of remarkable grace.
    Ophelia, a remarkable woman much in dispute with Hamlet.
    Hamlet, the flatterer of Andersen Insulting A/S.

                    Act I: Hamlet's insults and flattery.
    
                    Scene I: The insulting of Romeo.
    

    [Enter Hamlet and Romeo]

    Hamlet:
    You lying stupid fatherless big smelly half-witted coward!
    You are as stupid as the difference between a handsome rich brave
    hero and thyself! Speak your mind!

    You are as brave as the sum of your fat little stuffed misused dusty
    old rotten codpiece and a beautiful fair warm peaceful sunny summer's
    day. You are as healthy as the difference between the sum of the
    sweetest reddest rose and my father and yourself! Speak your mind!

    You are as cowardly as the sum of yourself and the difference
    between a big mighty proud kingdom and a horse. Speak your mind.

    Speak your mind!

    [Exit Romeo]

                    Scene II: The praising of Juliet.
    

    [Enter Juliet]

    Hamlet:
    Thou art as sweet as the sum of the sum of Romeo and his horse and his
    black cat! Speak thy mind!

    [Exit Juliet]

                    Scene III: The praising of Ophelia.
    

    [Enter Ophelia]

    Hamlet:
    Thou art as lovely as the product of a large rural town and my amazing
    bottomless embroidered purse. Speak thy mind!

    Thou art as loving as the product of the bluest clearest sweetest sky
    and the sum of a squirrel and a white horse. Thou art as beautiful as
    the difference between Juliet and thyself. Speak thy mind!

    [Exeunt Ophelia and Hamlet]

                    Act II: Behind Hamlet's back.
    
                    Scene I: Romeo and Juliet's conversation.
    

    [Enter Romeo and Juliet]

    Romeo:
    Speak your mind. You are as worried as the sum of yourself and the
    difference between my small smooth hamster and my nose. Speak your
    mind!

    Juliet:
    Speak YOUR mind! You are as bad as Hamlet! You are as small as the
    difference between the square of the difference between my little pony
    and your big hairy hound and the cube of your sorry little
    codpiece. Speak your mind!

    [Exit Romeo]

                    Scene II: Juliet and Ophelia's conversation.
    

    [Enter Ophelia]

    Juliet:
    Thou art as good as the quotient between Romeo and the sum of a small
    furry animal and a leech. Speak your mind!

    Ophelia:
    Thou art as disgusting as the quotient between Romeo and twice the
    difference between a mistletoe and an oozing infected blister! Speak
    your mind!

    [Exeunt]
    [/code]

    http://shakespearelang.sourceforge.net/report/shakespeare/


  • :belt_onion:

    Words are passé - use Piet and you can draw your program instead, saving reams of paper!

    Hello World

    Does what you'd expect

    Hello world in Piet Another hello world in Piet - this one animated (yes, it really works)

    Calculate π

    Piet program for calculating Pie

    For the curious, there are more examples here



  • Why use colors or numbers or symbols or integer constants or strings when you can use ALL CAPS ONES AND ZEROES?

    Comes with a free brainfuck compiler!



  • @Unixwolf said:

    COBOL was developed along time ago -- sometime around the K-Pg boundary. Way back then systems used 6 bit codes. That meant ten digits, a couple of control characters, a little bit of punctuation, and one alphabet. As every good monotheist knows, you can't spell GOD in an all lower case alphabet.

    Oh, dear. I remember *using* a computer that had a thoroughly 6-bit encoding. The machine was a CDC Cyber something-or-other that had an 18-bit address space, giving it 256 kibi-words, where one word was 60 bits. The character encoding was the weird CDC Display Code, which allowed you to fit 10 characters into a word of memory because they were 6 bits (not 6 of 8, just 6). If you bent the rules of C somewhere far, far beyond breaking point (you'd need to allow upper-case keywords and 6-bit characters for starters), you'd find yourself needing a trigraph to encode :, and you would also find that ':' == '\000' was true...

    All in all, that machine was a major WTF in its own right...



  • @ben_lubar said:

    @tar said:
    Declare two global variables (because there are no local variables):

    I recall an esoteric language that had more global variables than COBOL.


    I looked at that. It seems like one of those exercises in bloodymindedness that programmers are so fond of. And it contains a linguistic error.

    or can be declared with natural English phrases:

    Code: Select all
    ONE MILLION TWO HUNDRED THIRTY FOUR THOUSAND FIVE HUNDRED SIXTY SEVEN

    The understood words are:
    ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE TEN ELEVEN TWELVE THIRTEEN FOURTEEN FIFTEEN SIXTEEN SEVENTEEN EIGHTEEN NINETEEN TWENTY THIRTY FORTY FIFTY SIXTY SEVENTY EIGHTY NINETY HUNDRED THOUSAND MILLION BILLION TRILLION

    Sorry guys, but with that word list, you can only recognise numbers written in American. To recognise numbers written in English, you need to include AND and A in the list, because in English, 123 is written and spoken as "A hundred and twenty three". And it makes encoding zero difficult by not accepting this word...

    And me, I'd argue that it has fewer global variables than other global-heavy languages because it has only one namespace for variables, so we all have to share them.

    And you always had to (for the sake of politeness if nothing else) include information on where you found information on something, especially if you don't give us the name of the thing.


  • Discourse touched me in a no-no place

    @ben_lubar said:

    Why use colors or numbers or symbols or integer constants or strings when you can use ALL CAPS ONES AND ZEROES?

    1. because that's dumb
    2. because your program has a bug that makes it run forever (or did you ever fix that?)



  • Discourse touched me in a no-no place

    Ben, I don't like you[1] enough to stalk your github, so if you don't announce that shit here, I'll never find out.

    [1] rest assured it's probably not personal, or else it is the way the DI in Old Man's War made it personal with his recruits.



  • BenchmarkBFParse 10000 120652 ns/op 16585 B/op 25 allocs/op
    BenchmarkWrite 20 91877813 ns/op 73039200 B/op 32141 allocs/op
    BenchmarkBITParse 1 28594398973 ns/op 708173448 B/op 43683317 allocs/op
    BenchmarkHello 1 406385529484 ns/op 38885518880 B/op 2430344909 allocs/op



  • I need to figure out if Hello World actually prints anything. I know it terminates now, which is nice.


  • Discourse touched me in a no-no place

    @ben_lubar said:

    it terminates now

    Sticking a random halt() in the generated code doesn't count, Ben.



  • Ok, it seems that because I'm using value types instead of pointer types, it's allocating a bajillion bytes of memory

    37838.63MB of 38004.75MB total (99.56%)
    Dropped 45 nodes (cum <= 190.02MB)
    Showing top 10 nodes out of 24 (cum >= 19780.30MB)
          flat  flat%   sum%        cum   cum%
    18340.78MB 48.26% 48.26% 18340.78MB 48.26%  github.com/BenLubar/bit.(*VarExpr).run
     9603.65MB 25.27% 73.53% 19780.30MB 52.05%  github.com/BenLubar/bit.NextExpr.run
     5553.08MB 14.61% 88.14%  5553.08MB 14.61%  github.com/BenLubar/bit.varVal.addr
     3694.06MB  9.72% 97.86%  3694.06MB  9.72%  github.com/BenLubar/bit.(*BitExpr).run
      638.51MB  1.68% 99.54%   638.51MB  1.68%  github.com/BenLubar/bit.(*lex).Lex
        8.55MB 0.023% 99.56%   649.79MB  1.71%  github.com/BenLubar/bit.(*yyParserImpl).Parse
             0     0% 99.56% 12994.70MB 34.19%  github.com/BenLubar/bit.(*AddrExpr).run
             0     0% 99.56% 29761.95MB 78.31%  github.com/BenLubar/bit.(*AssignStmt).run
             0     0% 99.56%  7447.11MB 19.60%  github.com/BenLubar/bit.(*JumpRegisterStmt).run
             0     0% 99.56% 19780.30MB 52.05%  github.com/BenLubar/bit.(*NextExpr).run


  • Actually, it looks like I'm allocating memory for each value passed between expressions multiple times.



  • 806.91MB of 815.44MB total (98.95%)
    Dropped 14 nodes (cum <= 4.08MB)
    Showing top 10 nodes out of 31 (cum >= 11.50MB)
    flat flat% sum% cum cum%
    653.51MB 80.14% 80.14% 653.51MB 80.14% github.com/BenLubar/bit.(*lex).Lex
    64.62MB 7.92% 88.07% 64.62MB 7.92% bytes.makeSlice
    20.05MB 2.46% 90.53% 20.05MB 2.46% strings.Repeat
    16.08MB 1.97% 92.50% 70.03MB 8.59% github.com/BenLubar/bit/brainfuckc.(*Writer).assign
    14.56MB 1.79% 94.28% 34.61MB 4.24% github.com/BenLubar/bit/brainfuckc.(*Writer).offset
    12.03MB 1.48% 95.76% 669.54MB 82.11% github.com/BenLubar/bit.(*yyParserImpl).Parse
    8.54MB 1.05% 96.80% 52.24MB 6.41% github.com/BenLubar/bit/brainfuckc.(*Writer).increment
    6.53MB 0.8% 97.61% 17.20MB 2.11% github.com/BenLubar/bit/brainfuckc.(*Writer).jump
    6MB 0.74% 98.34% 11.50MB 1.41% github.com/BenLubar/bit.NextExpr.simplify
    5MB 0.61% 98.95% 11.50MB 1.41% github.com/BenLubar/bit.AddrExpr.simplify


  • Discourse touched me in a no-no place

    Did your internet just get faster because you're not paging out that other 38GB of vm to the world?



  • It's not 38GB of memory, it's 38GB of allocations. The garbage collector worked overtime.



  • If anyone wants the source code generated by the brainfuck compiler, here it is:

    hello.bit.gz (204.2 KB)



  • @Steve_The_Cynic said:

    a CDC Cyber something-or-other that had an 18-bit address space, giving it 256 kibi-words, where one word was 60 bits. The character encoding was the weird CDC Display Code, which allowed you to fit 10 characters into a word of memory because they were 6 bits (not 6 of 8, just 6).

    Then there was the whole business about zero-padding (that is, colon-padding) to the end of the word meaning end-of-line, 12-bit ^-prefix encodings for lowercase characters and other delights.

    It takes skill to devise a character encoding that makes EBCDIC look sane by comparison, and CDC rose to the challenge. Good times.


  • Discourse touched me in a no-no place

    @ben_lubar said:

    It's not 38GB of memory, it's 38GB of allocations.

    Hush, Ben, you're ruining my "Ben's Internet sucks" joke.



  • @ben_lubar said:

    If anyone wants the source code generated by the brainfuck compiler, here it is:

    hello.bit.gz (204.2 KB)

    Oh God can I beat the rush before the server gets DDoSed!

    ... I honestly don't know why Ben L stills posts here.


  • Discourse touched me in a no-no place

    @blakeyrat said:

    I honestly don't know why Ben L stills posts here.

    I simply assume it's an attempt to maintain a SpongeBob-like demeanor calculated to make you eventually snap, Squidward-like, and get hauled off to a mental institution.


  • 🚽 Regular

    @blakeyrat said:

    Oh God can I beat the rush before the server gets DDoSed!

    < "Ben's Internet sucks" joke >



  • I recently had to explain to a retired mainframe programmer, why the mix of
    5 bit codes and encryption (pre 1950 style) didn't mix very well, which
    meant that the poor old sigops had to spell out numbers.
    Among my treasures -- IBM flowchart stencil, Faber-Castell Novo Duplex 2/83
    slide rule etc - is my old HP-16 Computer Scientist Calculator. It dates
    from about 1987, and is probably the first "virtual machine" I ever saw. I
    can set flags to adjust the word size (16 - 64 bits) and switch between 1's
    and 2's complement arithmetic. Imagine trying to write C string processing
    functions on a system with +ve and -ve zeros!



  • @Zecc said:

    < "Ben'sTDWTF's Internet sucks" joke >

    FTFY


Log in to reply