Document

プログラミングパラダイム
さまざまな計算のモデルにもとづく、
プログラミングの方法論
1. 手続き型
2. 関数型
3. オブジェクト指向
4. 代数
5. 幾何
参考書
各パラダイムごとの解説は多い。ここでは複
数のパラダイムをまとめたもののみを挙げる。
•新しいプログラミングパラダイム
–井田哲雄・田中二郎 編、共立出版(1989)
•続新しいプログラミングパラダイム
–井田哲雄編、共立出版(1990)
パラダイム変化の流れ
1. 手続き型(最初の方法, ’70)
•
•
コンピュータの仕組みを記述
変数←状態
x := x+y;
•
•
/* 左辺値 */
構造化プログラミング
命令的(imperative)
2. 論理型、関数型(’70後半~)
•
演算器
記憶
宣言的(declarative)
3. オブジェクト指向(’80年代)
機械モデルから抽象的で人間中心のモデルへ
手続きプログラミングの例
任意個数の整数の和を求めるPascalプログラム
procedure sum_of_sequence ;
var i, s : integer ;
begin
s := 0 ;
while i < > -9999 do
begin
readline(i) ;
s := s+i ;
end ;
write(s) ;
end ;
手続き型+構造化プログラミングの弱点
• 背景となる計算モデル(テューリングマシ
ン)
は動作(意味)を把握しにくい。
• プログラム自体を対象にすること(メタプロ
グラミング)ができない。
– プログラムの性質が意味対象と乖離
• 作成あるいは変更のプロセスを軽視
関数型プログラミング
• 計算を関数でモデル化(Church λ-Calculus)
• リスト等、簡単なデータ構造(プログラム自身を格納する)
• 数学的帰納法で再帰プログラム
リストで与えられた整数の和をもとめるMLプログラム
sum_of_sequence [ ] = 0
sum_of_sequence (a : s) = a + sum_of_sequence s
呼び出し
sum_of_sequence [1,3,7] ⇒11 (戻り値)
関数型プログラミングの利点
;データとコード
(+ 1 3)
;==>4
'(+ 1 3)
;==>(+ 1 3)
(eval '(+ 1 3))
;==>4
(eval (cons '+ '(1 3)))
;==>4
;データとしての関数
(lambda (x) (* x x))
;==>(lambda (x) (* x x))
(funcall (lambda (x) (* x x)) 3)
;==>9
(setq two-times '(lambda (x) (* x x)))
;==>(lambda (x) (* x x))
(funcall two-times 3)
;==>9
(fset 'ftwo-times two-times)
(ftwo-times 3)
;==>9
論理型プログラミング
• 論理式がプログラム
• 意図する述語の否定を入力して証明(背理法)
• 反例が代入される。
プログラム例
sum_of_sequence([ ],0)←
sum_of_sequence(a : s, n) ←
sum_of_sequence(s, n1) ∧ n=a+n1
入力(クエリ) ←sum_of_sequence([1,3,7], n)
出力 n=11
オブジェクト指向
• 構造化プログラミングの拡張
– フィールド(内部変数)
– メソッド(内部関数)
• 継承(inheritance)
• 隠蔽または、カプセル化(encapsulation)
ユーザ定義クラスの演算の例
/*
"Complex.java"
複素数(和と積を実装) */
public class Complex{
double real,image;//実部と虚部
//wと成す角(wから計る)
double angle(Complex w){
double ang=Math.atan2(image,real);
double ang_w=Math.atan2(w.image,w.real);
return ang-ang_w;
}
//コンストラクタ:パラメタは実部と虚部
Complex(double r, double i){
real=r;
image=i;
}
//和:パラメタの複素数に自分を加えて返す。
Complex plus(Complex w){
return new
Complex(real+w.real,image+w.image);
}
//積:パラメタの複素数に自分を掛けて返す。
Complex times(Complex w){
return new Complex(real*w.real-image*w.image,
//値表示(テスト用)
void print(){
System.out.println(real+"+"+image+"i");
}
//テスト
public static void main(String[] args){
Complex z1,z2;
z1=new Complex(2.3,4.7);
z2=new Complex(3.0,12.8);
z1.plus(z2).print();
z1.times(z2).print();
}
real*w.image+image*w.real);
}
}
パラダイムの融合(’90~)
• CLOS (CommonLisp Object System)
– CommonLispのオブジェクト指向機構(ANSI標準)
• λ-Prolog
– 論理型言語の項にλ式を含める。
• MLのmodule
– 隠蔽:型宣言(シグニチャ)
– 継承:ファンクター
– オブジェクト生成不可
関数型とオブジェクト指向
クロージャ(CommonLisp)は関数を実行する環境ごと保持する。
(defun generate-num ()
(let ((n 0))
#'(lambda ()
(prog1 n
(setq n (+ n 1))))))
(setq counter (generate-num))
(funcall counter)
;==>0
(funcall counter)
;==>1