120 likes | 336 Views
プログラミングパラダイム. さまざまな計算のモデルにもとづく、 プログラミングの方法論 手続き型 関数型 オブジェクト指向 代数 幾何. 参考書. 各パラダイムごとの解説は多い。ここでは複数のパラダイムをまとめたもののみを挙げる。 新しいプログラミングパラダイム 井田哲雄・田中二郎 編、共立出版(1989) 続新しいプログラミングパラダイム 井田哲雄編、共立出版(1990). 演算器. 記憶. パラダイム変化の流れ. 手続き型(最初の方法, ’70) コンピュータの仕組みを記述 変数←状態 x := x+y; /* 左辺値 */
E N D
プログラミングパラダイム さまざまな計算のモデルにもとづく、 プログラミングの方法論 • 手続き型 • 関数型 • オブジェクト指向 • 代数 • 幾何
参考書 各パラダイムごとの解説は多い。ここでは複数のパラダイムをまとめたもののみを挙げる。 • 新しいプログラミングパラダイム • 井田哲雄・田中二郎 編、共立出版(1989) • 続新しいプログラミングパラダイム • 井田哲雄編、共立出版(1990)
演算器 記憶 パラダイム変化の流れ • 手続き型(最初の方法, ’70) • コンピュータの仕組みを記述 • 変数←状態 x := x+y; /* 左辺値 */ • 構造化プログラミング • 命令的(imperative) • 論理型、関数型(’70後半~) • 宣言的(declarative) • オブジェクト指向(’80年代) 機械モデルから抽象的で人間中心のモデルへ
手続きプログラミングの例 任意個数の整数の和を求めるPascalプログラム procedure sum_of_sequence ; vari, s : integer ; begin s := 0 ; whilei < > -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 (戻り値)
関数型プログラミングの利点 ;データとしての関数 (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 ;データとコード (+ 1 3) ;==>4 '(+ 1 3) ;==>(+ 1 3) (eval '(+ 1 3)) ;==>4 (eval (cons '+ '(1 3))) ;==>4
論理型プログラミング • 論理式がプログラム • 意図する述語の否定を入力して証明(背理法) • 反例が代入される。 プログラム例 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)
ユーザ定義クラスの演算の例 //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(); } } /* "Complex.java" 複素数(和と積を実装) */ 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); }
パラダイムの融合(’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