yamicha.com's Blog - Presented by yamicha.com
Blog yamicha.com's Blog - 2018/09 の記事
[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]

yamicha.com's Blog
 諸事情により、現在更新休止中。ご了承ください。もし今後ブログを再開することがあるとすれば、その際にはこのブログスクリプトではなく、新しく開発したものによるかもしれません。
 当ブログ管理者についてはこちらをご参照。
開発魔法(737)
社会問題(733)
お知らせ(11)
質問・バトン回答(15)
ゲスト出演(8)
経済・知的財産(150)
ゲーム開発(182)
[Ada] 勝手に補足
- Note
- 金配りの次の一手


- Endless Ultimate Diary
- 銃世界

漢字バトン
- うるる雑記帳
- 漢字接力棒

ツキアイゲノムバトン
- ブログ@うにうに画像倉庫
- あぶ内閣

縺イ縺セ縺、縺カ縺励ヰ繝医Φ
- 月夜のボヤキ
- 騎士サーラバトン
パスワードを使う
名無し (2012/02/27)


開発者解放裁判
yamicha.com (2010/03/14)
Winnyに関しては、私も「純白」とまでは考えておりませんし、使用し..

開発者解放裁判
通りすがり (2010/03/08)
winnyに関しては「ダウンロードソフト板」なんてところを拠点に開発..

新型インフルエンザの恐怖
いげ太 (2009/11/03)
> C#などの「int Some(int , int)」は、F#では「(int * int) ->..

時効に関する思考
yamicha.com (2009/08/31)
>いげ太さんコメントありがとうございます。手元にドキュメントが少..
Homepage
Blog Top
Normal View
List View
Search
Calendar
Comment List
Trackback List
Blog RSS
Send Trackback
Phone Mode
Administrator
yamicha.com
Blog
るううるる。
Source
法令データ提供システム
FindLaw
Development
Java2 Platform SE 6
Java EE 6 API
MySQL Developer Zone
PHP Reference
MSDN Library
Ada Reference Manual
Objective Caml
Python Documentation
Erlang
Prolog Documents
改欠くクラブ
2008/08/30(Sat)17:59:41
 民主党の4氏が党を離脱し、「改革クラブ」なる新党を立ち上げることが分かりました。ただし、このままでは基準の5人を満たさず、政党要件に該当しないため、政党交付金を受け取ることはできません。参院選で「姫の虎退治」のフレーズで有名となった姫井氏も当初は参加する予定でしたが、すぐに方針を撤回しました。
 日本では離党や結党はかねてから頻繁に発生しており、特に珍しいわけでもありません。いわゆる「郵政解散」からの動きを見ても、国民新党、新党日本、新党大地などの小さな政党が乱立し、少しさかのぼれば民主党と自由党の合併、自民党と保守新党の合併など、様々な結党や合併が行われています。
 しかし、今回の「改革クラブ」はルール違反であるといわなければなりません。参院選では「民主党が」第一党となりましたが、これは人々が民主党を勝たせようとしたためです。姫井氏の場合にしてもそうで、自民党の地盤を覆して民主党が勝利したのは、その地域の多くの人が民主党勝利を望んだからです。低IQ選挙のような極端なことが起きない限り、選挙の勝敗はこうして決まります。
 それでは、その勝たせた議員が突然政党を離脱し、得た議席を使って新党に移籍するなどと言い出したら、これは投票した人の期待に沿う行動でしょうか。ましてや、それが「小沢氏の体制が気に入らない」という理由ならなおさらです。私も小沢氏ではダメと考えてはいますが、選挙後に突然代表が変わって方針が大幅に変化し、その方針についていけないというならまだしも、出馬の時点で代表が小沢氏であることは分かっていたはずなのです。
 郵政離党のケースを考えても、自民党が「落下傘」を仕掛けてきたことで、造反議員は孤立無援の戦いを余儀なくされたのですが、この場合は選挙の時点で自民党を取るか造反議員を取るかを選ぶことができました。今回の「改革クラブ」を郵政政局に例えれば、郵政民営化を一大争点にした選挙で勝った挙句、すぐに離党して郵政民営化反対政党を作るようなものです。とはいえ、自民党には郵政選挙の比例区で復活当選した挙句、料理番組の収録と称して郵政民営化の採決をサボった人もいるようですが、これはまた別の話です。
 すなわち、「改革クラブ」などというものをどうしても立ち上げたいのであれば、議員辞職して立ち上げを発表するか、次の選挙でこれを作って国民の審判を仰ぐしかないのです。国民の意に反し、民主党議員として得た議席を持ち逃げしてそれを使い、ましてや政党交付金までもを受け取ろうなどという言い分は通用しません。このようなやり方を用いたところで、新党の構成員にはマイナスイメージがつくだけですし、一時的に参加を表明した姫井氏の信用も下落したことでしょう。
 しかし、改革クラブの面々が抱いたであろう「小沢氏ではダメ」という不安には同意します。現在の日本は是が非でも政権交代が必要な状況にあります。仮に民主党が成果を出せなくても、利権の一掃と競争原理の導入という目的は果たされます。それこそが政権交代のある政治状況の目指すところです。とはいえ、現在の日本の切羽詰った状況を考えれば、「政権さえ変われば後はどうでも構わない」とはいきません。
 それでは、小沢民主党にそれは可能でしょうか。やってみないことには何ともいえませんが、確率は低いと言わざるを得ません。要するに、小沢氏では無理なのです。しかしながら、これは福田氏では言うに及ばず、おそらく麻生氏でも無理でしょう。現在の日本に必要なのは、「何でも反対総理」や「アキバ総理」ではないのです。しかしながら、これができる人は自民党にも民主党にも少なからず存在するはずです。ただ、そうした人は彼らに比べて目立たないため、舵取り役をする機会に恵まれないのでしょう。「目立てば勝ち」という小泉タレント選挙の負の遺産といえます。
 このように、現在の政治は選択肢があるようで存在しない状況です。しかし、この閉塞した状況を打破したいという改革クラブの考えは、決して理解できないわけではありませんが、国民が特定の党に与えた議席を持ち逃げし、さらには政党交付金の入手までもくろむような行為は、状況の打破からは最も遠い行為であることも指摘しておかなければなりません。

 多くの言語では、条件分岐にif、ループにはwhileやfor(一部言語ではforはイテレータ)、何らかの機能の呼び出しには関数・メソッド・サブルーチンが使われます。こうした意味の構文はCOBOLにも当然存在します。ただし、COBOLには他の言語とは違う部分が少なからず存在しており、特にPERFORM文の多彩さには困ってしまうほどです。
 さて、プログラムというものがなぜ便利なのかといいますと、起動時あるいは起動中(開発者がその場限りの簡単な計算ツールを書く場合にはコード中の定数のことも)に好きな値を渡せば、プログラムがそれに応じた処理を行ってくれるためです。電卓が便利なのは任意の数の足し算や引き算が行えるからであって、仮に「1+2」しかできない電卓があるのなら、最初から計算などせず「3」を表示すれば足ります。
 言い換えれば、プログラムたるものには非常に高い確率でif文が存在しているはずなのです。まともなプログラムをif(switchや三項演算子など類型も含む)なしで書くことはできません。関数型言語はifなしで書くこともありますが、パターンマッチやガードといったifの代わりの技術を使用しますので、これもifと同じです。
 このように、ifは非常に重要な命令ですので、COBOLにも存在することは言うまでもありません。使い方も他の言語とほとんど同じです。
IDENTIFICATION DIVISION.
	PROGRAM-ID. BLOG.

DATA DIVISION.
	WORKING-STORAGE SECTION.
		01 VAR PIC 9(4).

PROCEDURE DIVISION.
	MAIN-PARAGRAPH.
		MOVE 10 TO VAR

		IF VAR = 10 THEN
			DISPLAY 'VAR は 10 です。'
		END-IF.
 条件の後のTHENは省略できます。いちいち書くのが面倒なためか、省略されて書かれることが多いようです。VBでも1行で書くのでなければ省略できますし、自然な仕様でしょう。
* THEN は省略できる
IF VAR = 10
	DISPLAY 'VAR は 10 です。'
END-IF
 COBOLのifにもelseが存在し、条件に当てはまらなかった場合の分岐を行うことができます。ただし、どうやらelse-if文は存在しないようです。else-ifを使いたければ、ifをネストするよりありません。
IDENTIFICATION DIVISION.
	PROGRAM-ID. BLOG.

DATA DIVISION.
	WORKING-STORAGE SECTION.
		01 VAR PIC 9(4).

PROCEDURE DIVISION.
	MAIN-PARAGRAPH.
*		この変数に任意の値を代入すれば分岐が変化
		MOVE 10 TO VAR

*		if-else が使えないので、if をネストして表現
		IF VAR < 10
			DISPLAY 'VAR は 10 未満です。'
		ELSE
			IF VAR < 20
				DISPLAY 'VAR は 20 未満です。'
			ELSE
				DISPLAY 'VAR は 20 以上です。'
			END-IF
		END-IF.
 しかし、if-elseが使えないのはやはり不便ということか、Cのswitchに類似するEVALUATE文も多く使われているようです。EVALUATEでは3つ以上の分岐も行えます。
IDENTIFICATION DIVISION.
	PROGRAM-ID. BLOG.

DATA DIVISION.
	WORKING-STORAGE SECTION.
		01 VAR PIC 9(4).

PROCEDURE DIVISION.
	MAIN-PARAGRAPH.
		MOVE 2 TO VAR

		EVALUATE VAR
			WHEN 1
				DISPLAY 'VAR は 1 です。'
			WHEN 2
				DISPLAY 'VAR は 2 です。'
			WHEN 3
				DISPLAY 'VAR は 3 です。'
			WHEN OTHER
				DISPLAY 'VAR はそれ以外です。'
		END-EVALUATE.
 このEVALUATE、COBOLの命令だけあって泣きたくなるほど記法が多いのですが、とりあえず代表的な記法だけでも取り上げておきます。しかし、たかだかifやswitchの代わりでありながら、どうしてこうも色々記法を作るのでしょうか。
* else-if を EVALUATE で実現する
MOVE 10 TO VAR

* switch ではなく else-if として使うなら、EVALUATE に TRUE を渡す
EVALUATE TRUE
	WHEN VAR < 10
		DISPLAY 'VAR は 10 未満です。'
	WHEN VAR < 20
		DISPLAY 'VAR は 20 未満です。'
	WHEN OTHER
		DISPLAY 'VAR は 20 以上です。'
END-EVALUATE.
 また、範囲を記述可能なswitchとして使うこともできます。
MOVE 10 TO VAR

EVALUATE VAR
	WHEN 0 THRU 9
		DISPLAY 'VAR は 0-9 です。'
	WHEN 10 THRU 19
		DISPLAY 'VAR は 10-19 です。'
	WHEN OTHER
		DISPLAY 'VAR はそれ以外です。'
END-EVALUATE.
 この「0 THRU 9」は、見ての通り「0から9」の意味です。このTHRUはTHROUGHの短縮形で、代わりにTHROUGHと書いても構いません。なお、THRUはPERFORM文など他の文にも登場しますが、これも同様にTHROUGHとも書けます。
 EVALUATEでは複数の変数を記述することもでき、ALSOを使って好きなだけ変数を並べられます。
EVALUATE VAR1 ALSO VAR2 ALSO VAR3 ...
 ALSOには変数だけでなくTRUEを置くこともでき、この場合はEVALUATEに普通にTRUEを置くのと同様、条件分岐を書けるようになります。複数の変数を使用する場合、そのうちのいくつかについては評価しないようにしたいことがありますが、その用途にはANYが使えます。ANYを記述した項目は必ずマッチするものとみなされます。
IDENTIFICATION DIVISION.
	PROGRAM-ID. BLOG.

DATA DIVISION.
	WORKING-STORAGE SECTION.
		01 VAR1 PIC 9(4).
		01 VAR2 PIC 9(4).

PROCEDURE DIVISION.
	MAIN-PARAGRAPH.
		MOVE 2 TO VAR1
		MOVE 150 TO VAR2

		EVALUATE VAR1 ALSO VAR2
*			VAR1 = 1 であればよく、VAR2 は無視
			WHEN 1 ALSO ANY
				DISPLAY 'VAR1 が 1 です。'
*			VAR2 が 0-100 であればよく、VAR1 は無視
			WHEN ANY ALSO 0 THRU 100
				DISPLAY 'VAR2 が 0-100 です。'
*			VAR1 = 2 かつ VAR が 101-200
			WHEN 2 ALSO 101 THRU 200
				DISPLAY 'VAR1 が 2 かつ VAR2 が 101-200 です。'
*			VAR1 = 2 かつ VAR が 201-300
			WHEN 2 ALSO 201 THRU 300
				DISPLAY 'VAR1 が 2 かつ VAR2 が 201-300 です。'
*			それ以外
			WHEN OTHER
				DISPLAY 'それ以外です。'
		END-EVALUATE.

 しかし、複数の変数を使って複雑な操作をするのであれば、最初からEVALUATE TRUEを使って条件を書いた方が良い気がしてなりません。他言語を経験し、else-ifの便利さを知っている開発者なら特に。
 以上の通り、COBOLの条件分岐はEVALUATE TRUEだけで事足ります。はっきり言ってEVALUATE ... ALSOもIFも使う必要がありません。しかし、単にIFのみ、あるいはIF-ELSEで可能な範囲で分岐するのであれば、わざわざEVALUATEを使うのではなくIFを使う方が簡単で分かりやすいため、IFは外せません。結局、EVALUATEのひたすら複雑な構文は無用の長物ということです。

 これで条件分岐はできるとして、開発において絶対に欠かせない命令がもう1つあります。言わずと知れたループ構文です。条件分岐同様、ループ処理ができない言語も皆無に近いでしょう。手続き型ならwhileやforを使うところを、関数型言語は再帰呼び出しによってループを表現しますが、これもやっていることはwhileと変わりません。
 他の一般的な言語とは違い、COBOLはPERFORM文でループを行います。これはCOBOLの困った癖なのですが、whileもforもPERFORMで実現できてしまいます。おかげでPERFORMにも大量の構文が生じており、訳が分からなくなっています。
 まずは単純なwhileの代わりから。ひとまず「1から10まで足したらいくつ」という古典的な問題を解いてみましょう。
MOVE 0 TO TOTAL
ADD 1 TO TOTAL
ADD 2 TO TOTAL
ADD 3 TO TOTAL
...
 言うまでもなく、これでも解けます。しかし、1から100まで、1000までとなったらこれは大変です。また、これはPERFORM文を使用するのが目的ですから、(1 + 10) / 2 * 5などという計算式で求めようという魂胆も当然却下なのは言うまでもありません。
 これの答えは、単純なPERFORMならこのようになるでしょうか。
IDENTIFICATION DIVISION.
	PROGRAM-ID. BLOG.

DATA DIVISION.
	WORKING-STORAGE SECTION.
		01 NUM PIC 9(4).
		01 TOTAL PIC 9(4).

PROCEDURE DIVISION.
	MAIN-PARAGRAPH.
		MOVE 1 TO NUM
		MOVE 0 TO TOTAL

		PERFORM UNTIL NUM > 10
			ADD NUM TO TOTAL
			ADD 1 TO NUM
		END-PERFORM
		
		DISPLAY TOTAL.
 PERFORM UNTILはwhileループとほぼ同じですが、UNTILだけに条件を満たした時点で抜けます。条件が満たされる限りループを続けるwhileとは逆です。
 PERFORMをforのように使用することもできます。これは通常のループの他、配列に順次アクセスするのにも用いられます。さらに、配列宣言にはインデックス変数まで自動的に作ってしまう構文が用意されています。
 まずは先ほどのコードを書き直したものを。
IDENTIFICATION DIVISION.
	PROGRAM-ID. BLOG.

DATA DIVISION.
	WORKING-STORAGE SECTION.
		01 NUM PIC 9(4).
		01 TOTAL PIC 9(4).

PROCEDURE DIVISION.
	MAIN-PARAGRAPH.
		MOVE 0 TO TOTAL

		PERFORM VARYING NUM FROM 1 BY 1 UNTIL NUM > 10
			ADD NUM TO TOTAL
		END-PERFORM
		
		DISPLAY TOTAL.
 forにあたるPERFORMを使用するには、PERFORM VARYINGを使います。使用するインデックス変数を指定した上で、FROMには開始時の値、BYにはループ毎に加算する値を指定します。つまり、任意の値からループを始めたり、任意の数だけ値を増やしていくことができます。
 配列には以下のように使用します。配列インデックスは配列宣言と同時に作成することもできますが、別に変数を用意しても構いません。
IDENTIFICATION DIVISION.
	PROGRAM-ID. BLOG.

DATA DIVISION.
	WORKING-STORAGE SECTION.
		01 FIBS.
*			IDX をインデックス変数として使用する
			03 FIB PIC 9(4) OCCURS 10 INDEXED IDX.

PROCEDURE DIVISION.
	MAIN-PARAGRAPH.
		MOVE 1 TO FIB(1) , FIB(2)

		PERFORM VARYING IDX FROM 3 BY 1 UNTIL IDX > 10
			MOVE FIB(IDX - 2) TO FIB(IDX)
			ADD FIB(IDX - 1) TO FIB(IDX)
		END-PERFORM

*		配列にはフィボナッチ数が格納されている
		DISPLAY FIB(8).
 その他、COBOLではインデックスを使わない回数ループも用意されています。PERFORM 10 TIMESと書けば、10回ループします。これは単に規定回数だけ処理を行いたい場合に便利です。
IDENTIFICATION DIVISION.
	PROGRAM-ID. BLOG.

DATA DIVISION.
	WORKING-STORAGE SECTION.
		01 FIB PIC 9(4).
		01 OLD PIC 9(4).
		01 FLIP PIC 9(4).

PROCEDURE DIVISION.
	MAIN-PARAGRAPH.
		MOVE 0 TO OLD
		MOVE 1 TO FIB

		PERFORM 20 TIMES
			MOVE FIB TO FLIP
			ADD OLD TO FIB
			MOVE FLIP TO OLD
		END-PERFORM

		DISPLAY FIB.
 これらのようなループ目的のPERFORMは「内PERFORM」と呼ばれています。
 PERFORMにはもう1つ機能があります。何とも類を見ない仕様なのですが、他の言語でいうサブルーチン呼び出しの機能も持っているのです。
 しかし、関数なりサブルーチンなりを呼び出すのであれば、まずはそれを用意しなくてはなりません。最初にCOBOLにおけるそれの書き方を。
PROCEDURE DIVISION.
	MAIN-PARAGRAPH.
		DISPLAY 'メインの領域です。'.
	ROUTINE-A.
		DISPLAY 'ROUTINE-A です。'.
 注意すべき点として、COBOLのPROCEDURE DIVISIONは中断しない限り最初から最後まで全部実行してしまうことがあります。この場合なら、MAIN-PARAGRAPHのみならず、ROUTINE-Aまで実行してしまいます。
 通常はSTOP RUNを記述して止めることが多いようです。ただし、STOP RUNは廃止が検討されている要素らしく、使用はあまり推奨されないものとされています。
PROCEDURE DIVISION.
	MAIN-PARAGRAPH.
		DISPLAY 'メインの領域です。'
		STOP RUN.
	ROUTINE-A.
		DISPLAY 'ROUTINE-A です。'.
 こうして宣言したROUTINE-Aなどのブロックは、PERFORMを使って好きな時に呼び出せます。PERFORMを使って呼び出した場合、最初から最後まで実行してしまうような事態にはなりません。このようなPERFORMは「外PERFORM」と呼ばれ、ループを主とする「内PERFORM」と区別されます。
IDENTIFICATION DIVISION.
	PROGRAM-ID. BLOG.

PROCEDURE DIVISION.
	MAIN-PARAGRAPH.
		PERFORM ROUTINE-A
		STOP RUN.
	ROUTINE-A.
		DISPLAY 'ROUTINE-A が呼ばれました。'.
	ROUTINE-B.
		DISPLAY 'ROUTINE-B が呼ばれました。'.
	ROUTINE-C.
		DISPLAY 'ROUTINE-C が呼ばれました。'.
	ROUTINE-D.
		DISPLAY 'ROUTINE-D が呼ばれました。'.
 このコードであれば、ROUTINE-Aのみが呼ばれます。
 COBOLのPERFORMは無駄なところで柔軟です。COBOLで良く使われるテクニックとして、特定の部分から特定の部分まで全部実行するPERFORMがあります。PERFORM ROUTINE-A THRU ROUTINE-Cなどと記述し、この場合であればROUTINE-Aから始まってROUTINE-Cを実行したところで終わるのですが、何とその間にあるコードもまとめて実行してしまいます
IDENTIFICATION DIVISION.
	PROGRAM-ID. BLOG.

PROCEDURE DIVISION.
	MAIN-PARAGRAPH.
*		ROUTINE-A , ROUTINE-B , ROUTINE-C をまとめて実行
		PERFORM ROUTINE-A THRU ROUTINE-C
		STOP RUN.
	ROUTINE-A.
		DISPLAY 'ROUTINE-A が呼ばれました。'.
	ROUTINE-B.
		DISPLAY 'ROUTINE-B が呼ばれました。'.
	ROUTINE-C.
		DISPLAY 'ROUTINE-C が呼ばれました。'.
	ROUTINE-D.
		DISPLAY 'ROUTINE-D が呼ばれました。'.
 これを実行すると、ROUTINE-A、ROUTINE-B、ROUTINE-Cがこの順番でコールされます。COBOLにはローカル変数といった便利なものがなく、データの受け渡しはすべて共通の変数を解して行うことになっており、引数や返り値といったことを考える必要がないため、CやJavaでは使い道がなさそうなこの記述もそれなりに生きてきます。
 外PERFORMはPERFORMだけあって、ループ呼び出しにも対応しています。
IDENTIFICATION DIVISION.
	PROGRAM-ID. BLOG.

DATA DIVISION.
	WORKING-STORAGE SECTION.
		01 POWER PIC 9(4).

PROCEDURE DIVISION.
	MAIN-PARAGRAPH.
		MOVE 1 TO POWER
*		2の10乗を求める
		PERFORM CALC-POWER 10 TIMES
		DISPLAY POWER
		STOP RUN.
	CALC-POWER.
		ADD POWER TO POWER.
 この記述ではCALC-POWERが10回呼び出されるため、2^10を求めることができます。
 あるいは、UNTILと組み合わせて使用しても構いません。
IDENTIFICATION DIVISION.
	PROGRAM-ID. BLOG.

DATA DIVISION.
	WORKING-STORAGE SECTION.
		01 POWER PIC 9(4).

PROCEDURE DIVISION.
	MAIN-PARAGRAPH.
		MOVE 1 TO POWER
		PERFORM CALC-POWER UNTIL POWER > 3000
		DISPLAY POWER
		STOP RUN.
	CALC-POWER.
		ADD POWER TO POWER.
 この場合、UNTILの効果によってPOWERが3000を越えた瞬間にループが終わるため、2のX乗のうち初めて3000を超える値(4096)が得られます。
 先ほどの「1から10を足す問題」はこのように書き換えられます。
IDENTIFICATION DIVISION.
	PROGRAM-ID. BLOG.

DATA DIVISION.
	WORKING-STORAGE SECTION.
		01 TOTAL PIC 9(4).
		01 IDX PIC 9(4).

PROCEDURE DIVISION.
	MAIN-PARAGRAPH.
		MOVE 0 TO TOTAL

		PERFORM ADD-TOTAL VARYING IDX FROM 1 BY 1 UNTIL IDX > 10

		DISPLAY TOTAL
		STOP RUN.
	ADD-TOTAL.
		ADD IDX TO TOTAL.
 ループと呼び出しについてはおおむねこの程度でしょうか。条件分岐とループがここまで難解な言語もあったものです。
カテゴリ [開発魔法][社会問題] [トラックバック 0][コメント 0]
<- 前の記事を参照 次の記事を参照 ->

- Blog by yamicha.com -