プログラミングパラダイム さまざまな計算のモデルにもとづく、 プログラミングの方法論 手続き型 関数型 オブジェクト指向 代数 幾何
参考書 各パラダイムごとの解説は多い。ここでは複数のパラダイムをまとめたもののみを挙げる。 新しいプログラミングパラダイム 井田哲雄・田中二郎 編、共立出版(1989) 続新しいプログラミングパラダイム 井田哲雄編、共立出版(1990)
パラダイム変化の流れ 手続き型(最初の方法, ’70) 論理型、関数型(’70後半~) オブジェクト指向(’80年代) コンピュータの仕組みを記述 変数←状態 x := x+y; /* 左辺値 */ 構造化プログラミング 命令的(imperative) 論理型、関数型(’70後半~) 宣言的(declarative) オブジェクト指向(’80年代) 機械モデルから抽象的で人間中心のモデルへ 演算器 記憶
手続きプログラミングの例 任意個数の整数の和を求めるPascalプログラム procedure sum_of_sequence ; var i, s : integer ; begin s := 0 ; while i < > -9999 do readline(i) ; s := s+i ; end ; write(s) ;
手続き型+構造化プログラミングの弱点 背景となる計算モデル(テューリングマシン) は動作(意味)を把握しにくい。 プログラム自体を対象にすること(メタプログラミング)ができない。 プログラムの性質が意味対象と乖離 作成あるいは変更のプロセスを軽視
関数型プログラミング sum_of_sequence [ ] = 0 計算を関数でモデル化(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) ;データとしての関数 (lambda (x) (* x x)) ;==>(lambda (x) (* x x)) (funcall (lambda (x) (* x x)) 3) ;==>9 (setq two-times '(lambda (x) (* x x))) (funcall two-times 3) (fset 'ftwo-times two-times) (ftwo-times 3) ;データとコード (+ 1 3) ;==>4 '(+ 1 3) ;==>(+ 1 3) (eval '(+ 1 3)) (eval (cons '+ '(1 3)))
論理型プログラミング 論理式がプログラム 意図する述語の否定を入力して証明(背理法) 反例が代入される。 プログラム例 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) フィールド(内部変数) メソッド(内部関数) 継承(inheritance) 隠蔽または、カプセル化(encapsulation)
ユーザ定義クラスの演算の例 /* "Complex.java" 複素数(和と積を実装) */ public class Complex{ 複素数(和と積を実装) */ public class Complex{ double real,image;//実部と虚部 //コンストラクタ:パラメタは実部と虚部 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, real*w.image+image*w.real); //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; } //値表示(テスト用) 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();
パラダイムの融合(’90~) CLOS (CommonLisp Object System) λ-Prolog MLのmodule 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 ;==>1