COBOL(コボル)は、事務処理用に開発されたプログラミング言語である。名前は「」(共通事務処理用言語)に由来する。非理系の事務員や官吏でもプログラミングできる言語として設計されたため、自然言語である英語に近い記述をめざしたコマンド語彙や構文(シンタックス)が採用されている。特に金額計算など事務処理用に広く使われている。COBOLは自然言語(英語)に近い構文を持つため、そのソースコードは記述が冗長にはなるが、可読性が高い。本のように、部、節、段落、文という階層で記述される。人によっては関数や数式だらけの言語よりもとっつきやすいといえる。リフレクションができないなど、モダンなプログラミング言語に比べて論理制御機能は貧弱である。一方、文字列解析や文字列編集、帳票、画面編集などの事務処理機能は豊富である。COBOLは仕様が古くレガシーな言語である。ただ、言語規格は拡張が続けられていて、2002年版以降ではオブジェクト指向にも対応して部品性を向上した。現実のプロジェクトで制約となるのは、COBOLの言語機能の不足よりは、稼働プラットフォーム、業務運用あるいは保守体制である場合も多い。COBOLは、科学技術計算向けのFORTRANに次いで国際的な標準化が行われた、初期のプログラミング言語である。過去のバージョンとの互換性を重視した国際標準規格にしたがって多くのプラットフォームでコンパイラが開発されてきたので、COBOL to COBOLのマイグレーション(プラットフォームの更新)は比較的容易である。膨大なCOBOLプログラムおよびそれらの処理するデータが、企業や政府機関に長年開発し続けられ稼働している。ガートナー発という情報によれば、メインフレームが世界1万サイト以上あって3万8千のレガシーシステムがあり、COBOLは全プログラム約3,100億行のうちの約65%の約2,000億行あって、毎年約50億行が増えているという。これはFORTRANとアセンブラを合わせた資産の数十億行に比べて圧倒的に多い。また、世界の商用データの約75%、商用トランザクションの80%以上(Google検索の200倍以上)である。COBOL開発者は85万人以上いるが、COBOL開発者の増加より減少がずっと速いという。日本国内では、2004-2009年のプロジェクトデータ2,417件をまとめたIPAのレポートによると、1位のJava(25.4%)に次いでCOBOLは16.8%で2位である。このように、誕生から半世紀たってもなお主流言語のひとつの座を占めている点で、他の初期の言語を引き離している。1950年代、事務処理言語は開発メーカーごとに異なっていた。その統一の必要性を認識していたアメリカ国防総省によって、事務処理用の共通言語の開発が提案され、CODASYL(Conference on Data Systems Languages、データシステムズ言語協議会)が設立された。そうした背景の下、1959年にCODASYLによって開発された共通事務処理用言語がCOBOLである。その後、1960年1月にCODASYL執行委員会によって最初の仕様書が承認され、合衆国政府印刷局に送られた。この最初の仕様書は1960年4月に発行され、通称COBOL-60と呼ばれているCOBOLの開発により、アメリカ政府の事務処理システムは全てCOBOLのみで納品されることとなった。これに伴い、COBOLは事務処理用言語として世界中に普及することになる。COBOL言語規格は、ローカル変数が作りにくく論理制御機能面が弱かった古典的言語からの脱皮を図っている。オブジェクト指向を採用し、入れ子プログラムを可能としたうえ、COBOLからCOBOLクラスライブラリのみならずJavaのクラスライブラリも呼べるようにするなど、相互運用性や共同開発容易性、安全性を改善してきている。2013年現在、COBOLプログラマーは意外に多い。実際はCOBOLと他のプログラミング言語の両方を使えるプログラマーの比率が多い。ただ、メインフレーム事業が全盛期を過ぎるとともに、ユーザ企業のアプリケーション資産を理解しているCOBOLプログラマー、さらにはCOBOLの分かるプログラマーやCOBOL流の設計の分かるSEさえ、転職や引退で減少しつつある。COBOL資産を多く抱えている企業の周辺では人材がまだ確保されて育成を図っている一方、その外側では要員不足がじわりと将来に不安の影を投げかけている。こうした状況の中、一部でメインフレームからオープン系のCOBOLへのマイグレーションが行われているとともに、従来のデータを従来のように処理できるJavaプログラムへの簡単・確実なコンバージョン、マイグレーションも望まれている。年齢を表すageという変数の値を、一定の年数を表すyearsという変数の値の分だけ増やす手続きは、例えば普通のプログラミング言語ではと書かれる。COBOLでも同様にCOMPUTE文によって000100 COMPUTE AGE = AGE + YEARS.と記述することもできるが、000100 ADD YEARS TO AGE. *> 英語でそのまま「年数を年齢に加える」という表現も可能である。このように、数学やアルゴリズムの知識を豊富にもっていなくても、全て現在形、語尾変化なし、など、構文上の約束事さえ覚えて、英語による理路整然とした記述ができれば、COBOLのプログラムを書けるように考えられている。つまり事務処理の手順を逐一細かく英語で書き下せば事務処理が電算化できるということである。さらにプログラムのコードそのものがプログラムの機能を説明する仕組みになっているので、そのまま読み下したときに分かりやすい。こういった特性を、まだ人工知能、自然言語処理の研究が浅い時期に追求してCOBOLを設計したのは、意義深く、産業的にも効果があった。ただ、ソフトウェアが大規模化し相互に絡み合うように接続されてきた現代、動詞や前置詞を明示するかどうかという命令記述の次元だけでは視点が不足である。モジュール性、処理の強力さを含めて可読性と保守性を総合評価しなおすと、場面によってはまたちがう結果も生じてくる。自然言語指向な書き方が優れているといっても、複雜な数式、関数を扱う科学技術計算分野における制御・演算には向いていない。二次方程式 A X + B X + C = 0 の解(の片方)を求める手続きは、COBOLでもCOMPUTE文を用いて簡潔に書こうとすれば、000100 COMPUTE X = (- B + (B ** 2 - 4 * A * C) ** 0.5) / (2 * A).と一文で済む。ただし、数式を極力使わない書き方にこだわれば、000100 MULTIPLY B BY B GIVING B-SQUARED. *> BにBを掛けてB二乗を得る000200 MULTIPLY 4 BY A GIVING FOUR-A. *> Aに4を掛けて4Aを得る000300 MULTIPLY FOUR-A BY C GIVING FOUR-A-C. *> 4AにCを掛けて4ACを得る000400 SUBTRACT FOUR-A-C FROM B-SQUARED GIVING D. *> B二乗から4ACを引いて判別式Dを得る000500 MOVE FUNCTION SQRT(D) TO ROOT-D. *> 累乗の文が無いため組み込み関数を使用000600 SUBTRACT B FROM ROOT-D GIVING NUMERATOR. *> √DからBを引いて「- B + √D」を得る000700 MULTIPLY 2 BY A GIVING TWO-A. *> Aに2を掛けて2Aを得る000800 DIVIDE NUMERATOR BY TWO-A GIVING X. *> 「- B + √D」を2Aで割って解(の片方)を得ると演算子1個あたり1文に膨れ上がって、見通しが明らかに悪くなる。もっとも、これほど複雜な式をこのように逐一書くプログラマはおよそ現代には存在しない。COBOLでは同じ処理を書くのに、少なくとも「COMPUTE ~」と書く必要もあり、他節に述べるようにいろいろなDIVISIONの記述も必要となるなど、モダンな言語より長くなりがちである。また、パズルのように巧妙な制御機能がさほど多彩に備わっているわけではない。Eclipseなどの統合開発環境でCOBOLも使えるようになったが、Javaのような小粒度なモジュールに関してもインタフェースを明確に記述するスタイルの言語よりも、そこでされるサポートは少ない。このようなことから、COBOLに習熟している人がモダンな言語でのプログラミング能力が高いとは限らない。それでも、世界的に蓄積され社会を動かしているCOBOL資産を保守・更新するという使命は重要である。他言語も習熟している技術者であっても、言語の欠点を多階層な共通モジュール作成やツール作成などでカバーしながら、社会基盤を支えるCOBOL関連プロジェクトで活動している。主にANSI COBOL 1985 の文法について述べる。COBOLの文法は英語の表現に近い。たとえば、ある変数 W-NO に対し数値 1 、W-CHARに'ABC'を代入する場合は、以下のような表記をする。000100 MOVE 1 TO W-NO.000200 MOVE 'ABC' TO W-CHAR.このように、COBOLの文法は自然言語(英語)に類似した文章的なものであることから、その可読性(ドキュメント性)の面で優れていると言われている。ただし数学の定理を例にとれば、それを自然言語に直したところで理解が容易になるわけではないため、これは否定派にはCOBOLの冗長性と捉えられる部分でもある。典型的なCOBOLの原始(ソース)プログラムは、FORTRANと同様にカラム固定形式で記述する。最近のCOBOLコンパイラには、行の長さが固定である必要がなく、一連番号の不要な自由形式をサポートするものがある。COBOLのプログラムは、次の4つのDIVISIONをこの順番で記述するのが基本となっている。「PROGRAM-ID」(プログラム識別名)を記述する。「AUTHOR」(作成者名)、「DATE-WRITTEN」(作成日)等の文法もあったが廃要素となった。プログラムが実行されるコンピュータの環境を記述する。「ENVIRONMENT DIVISION」は、「CONFIGURATION SECTION」(環境節)と「INPUT-OUTPUT SECTION」(I-O節)に大別される。プログラムで使用する変数及びデータ並びにその型について記述する。プログラムで使用する変数及びデータのすべては、DATA DIVISIONで定義しなければならない。「DATA DIVISION」は、「FILE SECTION」と「WORKING-STORAGE SECTION」に大別される。データの型の宣言は、PICTURE(PIC)句によって行う。呼ばれたプログラムが呼んだプログラムから引数でデータを受け取る場合は、それらの包含構造や基本項目の型を呼ばれたプログラムの「LINKAGE SECTION」で宣言する。COBOLのデータは、次の3つに分類される。COBOLの代表的な変数型(項類)に、次のものがある。COBOLでは固定長のレコード(繰り返しデータ単位)の中に固定長でデータ項目を含むという使い方が多い。たとえば、などである。データには包含関係の階層があり、領域再定義機能により同じメモリ領域を何通りかの構成で解釈できる。他の多くの言語(VB、C、Javaなど)では、改行までが繰り返しデータ単位で、その中の項目は可変長でコンマやタブなどの区切り記号で区切るという使い方が多い。たとえばCSV形式がある。最近のCOBOLコンパイラには、CSV形式の入出力をサポートするものもある。COBOLでは基本項目を並べて集団項目を作る。レベル番号を用いて階層構造を作る。OCCURS句により多次元配列を作る。これらによる固定長や可変長の「レコード」(C言語などの構造体に相当)のレイアウトを定義する。なお、「レコード」という型はCOBOLによって初めて導入された概念である。COBOLの階層的データの包含関係は、階層の深さを表すレベル番号"01"から"49"を各データ記述に付けることで記述される。こうした階層や領域再定義などのデータ構造をもつファイルやレコードの定義と処理は、COBOLの得意とするところで、Java言語および従来のJavaのクラスライブラリによってはなかなかうまく再現できない。COBOLでは、何百兆円という大きな金額の計算や、小数点以下何桁まで正確に複利計算をしても1円の誤差も出ない正確な小数計算が得意である。固定小数点数方式で整数とスケール(桁)を扱える数値項目は通常最大18桁(中間結果はそれ以上)あり、特に内部10進項目などの2進化10進数を用いれば、メモリを節約しつつ性能も確保できる。メインフレームではこれをサポートする専用のCPU命令まで設けられ、高速化が図られた。このアプローチは、10進2進変換に伴う誤差が避けられない浮動小数点数によって実数を近似値で表現しようとする他の言語の発想とは対照的である。FORTRANには浮動小数点数はあっても内部10進項目などはなかった。Javaでは任意桁の整数、小数を扱えるBigInteger、BigDecimalというクラスが提供されているが、文字配列で処理しているために金額計算、利息計算をCOBOLほど少ないCPUステップでは行えていない。COBOLでは無名の変数等として"FILLER"という名称を記述することができる。無名項目の"FILLER"は、COBOLにおける変数等の領域の定義は固定長となるため、そのような固定長領域内での予備的な領域の確保という意味合いも有している。たとえばで予備項目500バイトを含む製品レコードPRODUCT-RECを定義して他のシステムとデータを交換しはじめる。年月が経ってこのレコードに追加項目(広告開始日 AD-START-DATE)が発生したら、FILLERを削ってその新項目に宛てることで、授受データのレコード長を変更しなくて済む。FILLER によって、固定長レコードファイルの運用が円滑になった。ただ、この例で500バイトを使い切れば、やはりレコード長の変更が必要になる。だからといってむやみに長いFILLERを入れると、容量的な効率低下を招くのでバランスが必要である。製品が多くなって製品番号 PRODUCT-NO を8桁から12桁に拡張しようとすると、後続の項目群の開始番地が順繰りにずれてしまうので変更の影響が大きい。COBOLが扱うデータベースの領域定義も、多くの場合同様に固定長の項目からなるレコードという考えで行われてきた。システムが実際に入力したデータがプログラムが用意した桁数を1桁でも超えたとき、SIZE ERRORとしてエラー処理を行うのが普通である。オプションにより上を切り落として続行も可能。桁数が不足したときにデータのミスでなければ、プログラムとそのデータを授受するシステムのプログラムで一斉に桁数を増やす修正をしなければならない。データの変換も必要となる。このように桁数やバイト数の変更は大変なため、COBOLプログラマやSEは常に桁数やバイト数の設定や変更を意識し、プログラムの使用されるのが何十年でもその間になるべく桁溢れが起こらないように目を配って作業している。以上のような特徴は、固定長レコードやその中の文字列や数値を容易にかつ厳密に扱えるというCOBOLの大きな長所にともなう、保守、機能追加していく上での大きな短所である。実行されるプログラムの内、実際の処理部分のコードを記述する。引数を受け取る場合は、「PROCEDURE DIVISION USING 引数名 [, 引数名……]」という書き方をする。上記3つのDIVISIONを記述したあとやっと「PROCEDURE DIVISION」で実行手順のコードを記述する文法であるため、COBOLは「前置きが長い」言語ともいえる。COBOLの予約語の数は膨大で、文字数の長いものが多い。000100 IDENTIFICATION DIVISION.000200 PROGRAM-ID. HELLO.000300 PROCEDURE DIVISION.000400 DISPLAY 'HELLO, WORLD!'.000500 STOP RUN.出力この例では DISPLAY命令を使って文字列をコンソールまたは標準出力に出力している。COBOLはレコードレイアウトの決まったファイルの処理に使われることが多い。その場合はふつう、ファイル節(FILE SECTION)にレコードとそれを構成するデータ群の定義を書く。そして、実行部(PROCEDURE DIVISION)のREAD文、WRITE文などでそのレコードを読み書きする。作業領域節(WORKING-STORAGE SECTION)にデータを定義した例。000100 IDENTIFICATION DIVISION.000200 PROGRAM-ID. HELLO.000300 DATA DIVISION.000400 WORKING-STORAGE SECTION.000500 01 HELLO1 PIC X(15) VALUE 'HELLO, WORLD! 1'.000600 01 HELLO2.000700 03 FILLER PIC X(06) VALUE 'HELLO,'.000800 03 FILLER PIC X(01) VALUE SPACE.000900 03 FILLER PIC X(06) VALUE 'WORLD!'.001000 03 FILLER PIC X(01) VALUE SPACE.001100 03 FILLER PIC 9(01) VALUE 2.001200 PROCEDURE DIVISION.001300 DISPLAY 'HELLO, WORLD! 0'.001400 DISPLAY HELLO1.001500 DISPLAY HELLO2.001600 STOP RUN.出力000100 IDENTIFICATION DIVISION.000200 PROGRAM-ID. FIZZBUZZ.000300 DATA DIVISION.000400 WORKING-STORAGE SECTION.000500 01 I PIC 9(3).000600 01 HENSHU-IKI PIC X(4).000700 01 HENSHU-NUM REDEFINES HENSHU-IKI PIC ZZZ9.000800 01 DUMMY-IKI PIC X(1).000900 PROCEDURE DIVISION.001000 PERFORM VARYING I FROM 1 BY 1 UNTIL I > 100001100 EVALUATE FUNCTION MOD(I 3) = ZERO001200 ALSO FUNCTION MOD(I 5) = ZERO001300 WHEN TRUE ALSO TRUE001400 DISPLAY 'FIZZBUZZ'001500 WHEN TRUE ALSO FALSE001600 DISPLAY 'FIZZ'001700 WHEN FALSE ALSO TRUE001800 DISPLAY 'BUZZ'001900 WHEN OTHER002000 MOVE I TO HENSHU-NUM002100 UNSTRING002200 HENSHU-IKI DELIMITED BY ALL SPACE002300 INTO DUMMY-IKI HENSHU-IKI002400 END-UNSTRING002500 DISPLAY HENSHU-IKI002600 END-EVALUATE002700 END-PERFORM.002800 STOP RUN.出力COBOLでは剰余を求める際に、商・剰余それぞれを格納する変数を定義した上でDIVIDE文を用いることが多いが、商は不要で剰余のみが知りたい場合や、それを変数に格納しておく必要が無い場合は、組み込み関数のMODを用いても良い。また、COBOLでゼロサプレスを行った場合、0が空白に置き換えられるため、先頭に空白が生じる。ゼロサプレスを行い更に先頭の空白も除去したい場合は、空白を区切り文字に指定してUNSTRING文を用いれば良い。上記の例では、UNSTRING文実行後の変数DUMMY-IKIには常に空白が入り(区切り対象の文字列がいきなり空白=区切り文字から始まり、その前には何も無いため、何も入らない=空白が入る)、変数HENSHU-IKIには数字の部分だけが入る。000100 IDENTIFICATION DIVISION.000200 PROGRAM-ID. FIZZBUZZ.000300 DATA DIVISION.000400 WORKING-STORAGE SECTION.000500 01 I PIC 9(3).000600 01 HENSHU-IKI PIC X(8).000700 01 HENSHU-NUM REDEFINES HENSHU-IKI PIC Z(7)9(1).000800 01 DUMMY-IKI PIC X(1).000900 PROCEDURE DIVISION.001000 PERFORM VARYING I FROM 1 BY 1 UNTIL I > 100001100 MOVE SPACE TO HENSHU-IKI001200 IF FUNCTION MOD(I 3) = ZERO001300 MOVE 'FIZZ' TO HENSHU-IKI001400 END-IF001500 IF FUNCTION MOD(I 5) = ZERO001600 STRING001700 HENSHU-IKI DELIMITED BY SPACE001800 'BUZZ' DELIMITED BY SIZE001900 INTO HENSHU-IKI002000 END-STRING002100 END-IF002200 IF HENSHU-IKI = SPACE002300 MOVE I TO HENSHU-NUM002400 UNSTRING002500 HENSHU-IKI DELIMITED BY ALL SPACE002600 INTO DUMMY-IKI HENSHU-IKI002700 END-UNSTRING002800 END-IF002900 DISPLAY HENSHU-IKI003000 END-PERFORM.003100 STOP RUN.出力結果は実例3と同じであるが、STRING文による文字列の連結を利用することで、3の倍数かつ5の倍数(すなわち15の倍数)か否かの判定を無くしている。なお、上記の例におけるSTRING文は、Java等におけるhenshu_iki = henshu_iki + "Buzz"(或いはこれを略記したhenshu_iki += "Buzz")と同義である。CODASYLによって標準化が行われてきて、また、ANSIやISO/IEC JTC 1 SC22/WG4などによっても標準化されていた。1992年1月にCODASYLのCOBOL委員会とANSIのCOBOL委員会は一本化された。なお、国際規格は ISO/IEC 1989、日本規格は JIS X3002(旧JIS C 6205)である。CODASYLでは常時言語仕様の改定をおこなっており、その成果を1~5年ごとにとりまとめてCOBOLの仕様書を発行していた。
出典:wikipedia
LINEスタンプ制作に興味がある場合は、
下記よりスタンプファクトリーのホームページをご覧ください。