COBOL
COBOL(コボル)は、1959年に事務処理用に開発されたプログラミング言語である。名前は「Common Business Oriented Language」(共通事務処理用言語)に由来する。
非理系の事務員や官吏でもプログラミングできる言語として設計されたため、自然言語である英語に近い記述をめざしたコマンド語彙や構文(シンタックス)が採用されている。特に金額計算など事務処理用に広く使われている。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開発者の増加より減少がずっと速いという。
日本国内では、2016-2021年のソフトウェア開発データ1,476件をまとめたIPAのレポートによると、1位のJava(42.4%)に次いでCOBOLは16.3%で2位である。
このように、誕生から60年以上たってもなお主流言語のひとつの座を占めている点で、他の初期の言語を引き離している。
1950年代、事務処理言語は開発メーカーごとに異なっていた。その統一の必要性を認識していたアメリカ国防総省によって、事務処理用の共通言語の開発が提案され、CODASYL(Conference on Data Systems Languages、データシステムズ言語協議会)が設立された。そうした背景の下、1959年にCODASYLによって開発された共通事務処理用言語がCOBOLである。
その後、1960年1月にCODASYL執行委員会によって最初の仕様書が承認され、合衆国政府印刷局に送られた。この最初の仕様書は1960年4月に発行され、通称COBOL-60と呼ばれている
。
COBOLの開発により、アメリカ政府の事務処理システムは全てCOBOLのみで納品されることとなった。これに伴い、COBOLは事務処理用言語として世界中に普及することになる。
C言語やJavaなどの登場後も、COBOLは主に商用計算記述用として、主に金融業界や行政サービスなどで広く使用されている。
COBOL言語規格は、ローカル変数が作りにくく論理制御機能面が弱かった古典的言語からの脱皮を図っている。オブジェクト指向を採用し、入れ子プログラムを可能としたうえ、COBOLからCOBOLクラスライブラリのみならずJavaのクラスライブラリも呼べるようにするなど、相互運用性や共同開発容易性、安全性を改善してきている。
2019年現在、COBOL Cowboys社の調査では2000億行のCOBOLプログラムが現役で、フォーチュン500企業の90%がCOBOLプログラムを使い続けている。またマイクロフォーカス社のDerek Britton氏は「COBOLシステムを運用している組織が万単位で存在」「この言語が世界のトランザクション処理システムのうちの70%で用いられている」と述べた。
数多くの新しい言語やフレームワークが現れた現代、COBOLで作られるシステムはレガシーであり、システム刷新時に仕様を把握した有識者が居ない事や、新技術への対応の難しさが問題になる事がある。
「COBOLの冗長さ」は、時折ハッカージョークのネタにされる。例えばCOBOLのオブジェクト指向拡張案「ADD 1 TO COBOL GIVING COBOL」(C++のもじり)などである。
構造化プログラミングを提唱した計算機科学者エドガー・ダイクストラは、各種言語の欠点を挙げた中でCOBOLについて「COBOLを使っていると人は無能になってしまう。COBOLの教育は犯罪とみなすべきである。」と述べた。これが書かれたのは、企業ではCOBOLで新人教育がされ、構造化プログラミングも知らずにGO TO文だらけの巨大なスパゲティプログラムを普通に書いていてレビューと障害修正が大変だった1975年である。
2009年9月18日は「COBOL誕生50周年」とされ、マイクロフォーカスが50周年を祝うサイトを立ち上げた。これはCOBOLという名称が決定された1959年9月18日を、COBOLの誕生日としたものである。また、国内主要COBOLベンダーが設立した非営利団体であるCOBOLコンソーシアムは、最初の公的な仕様書であるCOBOL-60が発行された1960年4月をCOBOL誕生年月とし、2010年4月16日にCOBOL誕生50周年記念セミナーを行っている。
2009年11月、マイクロフォーカスのスチュアート・マギルは、「稼動中のCOBOLプログラムは全世界で2,400億行で、年間30億行が追加されている。全世界のCOBOLプログラマは200万人。フォーチュン500の90%の企業はCOBOLプログラムを使用中。」との趣旨の発言をした。
日本の国家資格である基本情報技術者試験(2000年度までは第二種情報処理技術者試験と呼ばれていた)の午後試験では2019年度まではCOBOLに関する内容が出題されていた(ただし自由選択制であり必須問題ではない)が、2020年度試験より廃止となった。代わりにPythonが追加されたが、さらに2023年度からはプログラミング言語の出題はすべて廃止になり、普遍的・本質的なプログラミング的思考力を問う擬似言語による出題となる予定。
年齢を表すageという変数の値を、一定の年数を表すyearsという変数の値の分だけ増やす手続きは、例えば普通のプログラミング言語では
(C言語などではのように略記できる)
と書かれる。COBOLでも同様にCOMPUTE文によって
と記述することもできるが、
(英語でそのまま「年数を年齢に加える」)
という表現も可能である。
このように、数学やアルゴリズムの知識を豊富にもっていなくても、全て現在形、語尾変化なし、など、構文上の約束事さえ覚えて、英語による理路整然とした記述ができれば、COBOLのプログラムを書けるように考えられている。つまり事務処理の手順を逐一細かく英語で書き下せば事務処理が電算化できるということである。さらにプログラムのコードそのものがプログラムの機能を説明する仕組みになっているので、そのまま読み下したときに分かりやすい。
こういった特性を、まだ人工知能、自然言語処理の研究が浅い時期に追求してCOBOLを設計したのは、意義深く、産業的にも効果があった。ただ、ソフトウェアが大規模化し相互に絡み合うように接続されてきた現代、動詞や前置詞を明示するかどうかという命令記述の次元だけでは視点が不足である。モジュール性、処理の強力さを含めて可読性と保守性を総合評価しなおすと、場面によってはまたちがう結果も生じてくる。
自然言語指向な書き方が優れているといっても、複雜な数式、関数を扱う科学技術計算分野における制御・演算には向いていない。二次方程式 A X2 + B X + C = 0 の解(の片方)を求める手続きは、COBOLでもCOMPUTE文を用いて簡潔に書こうとすれば、
と一文で済む。ただし、数式を極力使わない書き方にこだわれば、
(BをB倍し、B-SQUAREDに代入)
(Aを4倍し、FOUR-Aに代入)
(CをFOUR-A倍し、FOUR-A-Cに代入)
(B-SQUAREDからFOUR-A-Cを引き、Dに代入)
(Dの正の平方根を、ROOT-Dに代入)
(ROOT-DからBを引き、NUMERATORに代入)
(Aを2倍し、TWO-Aに代入)
(NUMERATORをTWO-Aで割り、Xに代入)
と演算子1個あたり1文に膨れ上がって、見通しが明らかに悪くなる。もっとも、これほど複雑な式をこのように逐一書くプログラマはおよそ現代には存在しない。
COBOLでは同じ処理を書くのに、少なくとも「COMPUTE ~」と書く必要もあり、他節に述べるようにいろいろなDIVISIONの記述も必要となるなど、モダンな言語より長くなりがちである。また、パズルのように巧妙な制御機能がさほど多彩に備わっているわけではない。Eclipseなどの統合開発環境でCOBOLも使えるようになったが、Javaのような小粒度なモジュールに関してもインタフェースを明確に記述するスタイルの言語よりも、そこでされるサポートは少ない。
このようなことから、COBOLに習熟している人がモダンな言語でのプログラミング能力が高いとは限らない。それでも、世界的に蓄積され社会を動かしているCOBOL資産を保守・更新するという使命は重要である。他言語も習熟している技術者であっても、言語の欠点を多階層な共通モジュール作成やツール作成などでカバーしながら、社会基盤を支えるCOBOL関連プロジェクトで活動している。
主にANSI COBOL 1985の文法について述べる。
COBOLの文法は英語の表現に近い。たとえば、ある数値型変数W-NOに対し数値100、英字型変数W-CHARに文字列'ABC'を代入する場合は、以下のような表記をする。
(または)
このように、COBOLの文法は自然言語(英語)に類似した文章的なものであることから、その可読性(ドキュメント性)の面で優れていると言われている。ただし、数学の定理を例にとれば、それを自然言語に直したところで理解が容易になるわけではないため、これは否定派にはCOBOLの冗長性と捉えられる部分でもある。
典型的なCOBOLの原始(ソース)プログラムは、FORTRANと同様にカラム固定形式で記述する。
1~6カラム目「一連番号」
各行を識別するために、6桁のシーケンシャル番号を記述することができる。
7カラム目「標識領域」
その行の標識を記述する。例えば、アスタリスクを記述すると、その行は注記行となる。
8~11カラム目「A領域」
12~72カラム目「B領域」
A領域およびB領域に、コードを記述する。ピリオドおよびその後に続くスペースを記述してコードの行末を示す。
最近のCOBOLコンパイラには、行の長さが固定である必要がなく、一連番号の不要な自由形式をサポートするものがある。
COBOLのプログラムは、次の4つのDIVISIONをこの順番で記述するのが基本となっている。
IDENTIFICATION DIVISION……見出し部
ENVIRONMENT DIVISION……環境部
DATA DIVISION……データ部
PROCEDURE 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の代表的な変数型(項類)に、次のものがある。
数字項目 (numeric item) - 例:99999 または 9(5)
英数字項目 (alphanumeric item) - 例:XXXXX または X(5)
英字項目 (alphabetic item) - 例:AAAAA または A(5)
数字編集項目 (numeric edited item) - 例:ZZZ,ZZ9
英数字編集項目 (alphanumeric edited item) - 例:AXX/XX/XX
COBOLでは固定長のレコード(繰り返しデータ単位)の中に固定長でデータ項目を含むという使い方が多い。たとえば、
<pre>
00076543SHOUYURAMEN         20121013
00076544SHIORAMEN           20111231
</pre>
などである。データには包含関係の階層があり、領域再定義機能により同じメモリ領域を何通りかの構成で解釈できる。
他の多くの言語(VB、C、Javaなど)では、改行までが繰り返しデータ単位で、その中の項目は可変長でコンマやタブなどの区切り記号で区切るという使い方が多い。たとえばCSV形式
<pre>
76543,SHOUYURAMEN,20121013
76544,SHIORAMEN,20111231
</pre>
がある。最近の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の大きな長所にともなう、保守、機能追加していく上での大きな短所である。
COBOLのデータ型の宣言で、COBOL85以前から可変長のデータ宣言も可能になっている。
COBOLの仕様拡張により、ポインタ操作も可能になっており、実装しているCOBOLコンパイラも複数、開発されている。
DBMSとの連携により、データベースを操作する場合、DBMS側でレコードの定義、ビューの定義などを行う。そのため、レコードのフィールド変更などがあっても、ビューなどで変更対象のフィールドを参照するアプリケーション以外は、修正や再コンパイルは必要ない。
RDBMSとの連携では、可変長データ、BLOBなど、多様なデータ型の扱いも可能となっている。ただし、COBOL側の受け渡しの変数の宣言は、COBOLコンパイラにより、COBOLの可変長データ型を使うものと、COBOLでは有効長を持つ固定長データ型を使うものなど、開発元による実装の違いがある。
階層型、ネットワーク型データベースをCODASYLが国際標準化した構造型データベースのNDLに準拠した埋込み型DMLを、IBM、富士通、日立などのメインフレームのCOBOLでは実装している。
標準SQLに準拠した埋込み型SQLを、IBM、富士通、日立などのメインフレームのCOBOLでは実装している。
実行されるプログラムの内、実際の処理部分のコードを記述する。
引数を受け取る場合は、「PROCEDURE DIVISION USING 引数名 [, 引数名……]」という書き方をする。
上記3つのDIVISIONを記述したあとやっと「PROCEDURE DIVISION」で実行手順のコードを記述する文法であるため、COBOLは「前置きが長い」言語ともいえる。
COBOLの予約語の数は膨大で、文字数の長いものが多い。
<pre>
HELLO, WORLD!
</pre>
この例では DISPLAY命令を使って文字列をコンソールまたは標準出力に出力している。
COBOLはレコードレイアウトの決まったファイルの処理に使われることが多い。その場合はふつう、ファイル節(FILE SECTION)にレコードとそれを構成するデータ群の定義を書く。そして、実行部(PROCEDURE DIVISION)のREAD文、WRITE文などでそのレコードを読み書きする。
作業領域節(WORKING-STORAGE SECTION)にデータを定義した例。
<pre>
HELLO, WORLD! 1
HELLO, WORLD! 2
</pre>
<pre>
(中略)
</pre>
COBOLでは剰余を求める際に、商・剰余それぞれを格納する変数を定義した上でDIVIDE文を用いることが多いが、商は不要で剰余のみが知りたい場合や、それを変数に格納しておく必要が無い場合は、組み込み関数のMODを用いても良い。
また、COBOLの数字項目は定義された桁数よりも少ない桁数の値が格納された場合、ゼロパディングした状態で扱うため、このまま表示させると001、002、…、098と先頭に0が補われて表示されてしまう。N桁で定義された数字項目に、正の整数nが格納された場合、その最上位桁の位置は左からN - \left \lfloor \log_{10} n \right \rfloorカラム目であるから、上記のようにと記述することで、パディングされた0を除いた部分だけを表示させることが出来る。
なお、0、負の数、小数を扱う場合は、下記のように数字編集項目によるゼロサプレスとUNSTRING文を組み合わせることでパディングされた0を除いて表示させることが出来る。
COBOLの数字編集項目によるゼロサプレスは、単純に0を空白に置き換えるだけであるから、先頭に空白が生じる(=整数部分が右寄せになる)。ゼロサプレスを行い更に先頭の空白も除去したい(=左寄せにしたい)場合は、空白を区切り文字に指定してUNSTRING文を用いれば良い。上記の例では、UNSTRING文実行後の変数DUMMY-IKIには常に空白が入り(対象の文字列がいきなり空白=区切り文字から始まり、その前には何も無いため、何も入らない=空白が入る)、変数HENSHU-IKIには数字の部分だけが入る。
出力結果は実例3と同じであるが、STRING文による文字列の連結を利用することで、3の倍数かつ5の倍数(すなわち15の倍数)か否かの判定を無くしている。なお、上記の例におけるSTRING文は、Java等における(あるいはこれを略記した)と同様の動作をする。
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の仕様書を発行していた。
COBOL-60
COBOL-61
手続き部の構成の変更、4つの部が出揃う
拡張COBOL-61(1963年)
(追加)ソート機能
(追加)報告書作成機能
(追加)算術文での複数の答え
(追加)CORRESPONDING機能
COBOL-65
第1次規格の元になる。
(追加)大記憶ファイルの処理機能
(追加)指標による添字付け、表引き
(廃止)誤り診断メッセージへの要求
(廃止)必須機能と選択機能の区分
COBOL-68
この年から開発報告 (JOD) 形式になる。
(追加)プログラム間連絡機能
(追加)映像端末処理用のSUSPEND文
(追加)割り算の余りを求める機能
(追加)注釈行
(追加)一般化されたCOPY機能
(追加)論理的なページあふれ条件の指定と検出
(追加)略語による記法
(変更)EXAMINE文の機能拡張
(廃止)PICTURE句と重複する編集句
(廃止)NOTE文、REMARKS段落
(廃止)DEFINE文
(廃止)一部の略記法
COBOL-69
(追加)通信機能
(追加)翻訳印刷におけるページ送り
(追加)実行時の日付と時刻の呼び出し
(変更)文字列操作機能
(追加)STRING文
(追加)UNSTRING文
(追加)INSPECT文
(廃止)EXAMINE文
(追加)SIGN句
(廃止)データ部の定数節
COBOL-70
第2次規格の元になる。
(追加)デバッグ機能
(追加)MERGE文
(追加)データ初期化のためのINITIALIZE文
(変更)報告書作成機能の全面的な改定
(廃止)RANGE句
COBOL-73
(追加)WRITE文によるページ送り
(追加)LINAGE句
(変更)INSPECT文の機能拡張
(変更)直接記憶装置アクセス機能を相対編成と索引編成に組み替え
(変更)登録集機能
(変更)再実行機能
(変更)独立項目記述と一連項目記述の相対位置の自由化
COBOL-76
(追加)データベース機能
(追加)ビット列操作
(変更)ファイル定義方法の整理
(廃止)独立項目(レベル番号77)
(廃止)ALTER
COBOL-78
第3次規格の元になる。
(追加)構造化プログラミング機能
(変更)プログラム間連絡機能
(変更)データベース機能
COBOL-81
(追加)浮動小数点
(追加)算術式による添字
(変更)正書法の改訂(自由書式の導入)
(廃止)デバッグ機能(デバッグ行以外)
(廃止)ENTER文
(廃止)CORRESPONDING機能
COBOL-84(25周年記念版)
第3次規格(補追)の元になる。
(追加)組み込み関数
(追加)データ検証 (VALIDATE) 機能
(追加)行の一部分に注釈を書く方法
(廃止)RERUN機能
COBOL-88
(追加)表SORT機能
(追加)定数の連結
(追加)画面制御機能
(追加)いくつかの組み込み関数
(廃止)区分化機能
(変更)語の長さを60字以下までとする。
COBOL-93(最終版)
(追加)マルチオクテット処理
(追加)ファイルの排他共用制御
(追加)いくつかの組み込み関数
(変更)語の長さを30字以下までにもどす。
グレース・ホッパー - COBOLの開発者。俗に「COBOLの母」と呼ばれる。