38
2019/6/27 1 プログラミング言語論 (Concepts on Programming Languages) 趙 建軍 情報知能工学部門 1 関数型プログラミング言語 (Functional Programming Languages) 2019.06.27 2 11

2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

  • Upload
    others

  • View
    4

  • Download
    0

Embed Size (px)

Citation preview

Page 1: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

1

プログラミング言語論(Concepts on Programming Languages)

趙 建軍情報知能工学部門

1

関数型プログラミング言語(Functional Programming Languages)

2019.06.272

第11回

Page 2: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

2

3

今日の講義

宣言型プログラミング

関数型プログラミング 歴史

関数型プログラム

プログラミングのパラダイム

4命令型

Page 3: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

3

プログラミングのパラダイム

5宣言型

宣言型プログラミングとは

宣言型プログラミング (Declarative programming)は、プログラミングパラダイムの名称だが、主として2種類の意味がある

第1の意味:処理方法ではなく対象の性質などを宣言することでプログラミングするパラダイムを意味する

第2の意味:純粋関数型プログラミング、論理型プログラミング、制約プログラミングの総称である

後者は前者の性質を持つ

6

Page 4: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

4

What vs How

7

命令型 vs 宣言型

8

Page 5: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

5

9

命令型 vs 宣言型

プログラミングのパラダイム

10宣言型

Page 6: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

6

プログラミングのパラダイム

11

関数型

12

関数型プログラミングとは (1)

Functional programming is style of programming in which the basic method of computation is the application of functions to arguments;

A functional language is one that supports and encourages the functional style.

Opinions differ, and it is difficult to give a precise definition, but generally speaking:

Page 7: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

7

関数型プログラミングとは (2)

様々な意見あり、詳細な定義は困難、けれども、一般には:

関数型プログラミングとは、計算の基本操作が引数に対する関数適用であり、プログラムは関数の合成であるとする プログラミングスタイル

関数型言語は、このプログラミングスタイルを支援し、ある意味で強制するプログラミング言語

13

関数型プログラミングとは (2)

関数型プログラミングとは複数の式を関数の適用によって組み合わせていくプログラミングスタイルである

Functional programming is a programming paradigm. A style of building the structure and elements of computer programs that treats computation as the evaluation of mathematical

functions and avoids changing-state and mutable data

14

Page 8: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

8

関数型 vs 命令型プログラム

命令型 Turing machine:計算機には「状態」があり、1

ステップずつ実行される命令によって、「状態」が変更されるもの

手順 (how) が決まっている。何をするか (what) は不鮮明

関数型 帰納的関数論:基本関数があって、それを合成

して複雑な関数を構成する 「状態」がない 何をすべきか (what) が決まっている。手順 (how)

は決まっていない 15

例 (1)

Summing the integers 1 to 10 in Java:

int total = 0;

for (int i = 1; i 10; i++)

total = total + i;

The computation method is variable assignment.

16

Page 9: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

9

例 (1)

Summing the integers 1 to 10 in Haskell:

sum [1..10]

The computation method is function application.

17

例 (2)

18

total = 0;for (i = 1; i <= 10; ++i)

total = total+i;

fun sum 0 = 0| sum n = n + sum (n-1);

変数への代入

関数の適用

Page 10: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

10

例 (3): 階乗関数

19

定義

0! = 1n! = n * (n-1)!

ML: 関数型

fun factorial 0 = 1| factorial n = n * factorial (n-1)

C: 通常

int factorial (int n) { int f;f = 1;while (n > 0) {

f = f * n;n = n – 1;

}return f;

}

C: 関数型的

int factorial (int n) { if (n == 0) return 1;else return n * factorial (n-1);

}

関数型 vs 命令型プログラム 表示的意味論によれば 命令型プログラムは関数型プログラムとして

記述することができる。なお、機械の状態を表すデータ構造を用いる

これは理論的結果である 私は“理論的” というのは“本当に正しい”

ということだと思うのだが(?)

実践にとってどんな意味があるか? 関数型言語を実応用に使うことができるか? コンパイラ, GUI, ネットワークのルータ, ….

20

Page 11: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

11

関数型プログラミングの特徴

21

純関数型プログラミング (pure functional programming)

first-class object としての関数

ラムダ式/ラムダ計算 (lambda calculus)

関数型プログラミングの特徴

純関数型プログラミング 式の値があれば、それはその部分式の値に

だけ依存する(つまり、副作用がない) 式は、評価されるたびに同じ値を持つ

22

参照の透明性 (tranceparency)

Page 12: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

12

純関数型プログラミングとは、変数や代入のないプログラミング

純関数型内部状態を持たない

命令型代入により内部状態が変化

23

関数型プログラミングの特徴

ほとんどの関数型言語は、代入操作を持つ

⇒ 純粋ではない

24

本質は、純粋な部分により支配されている

関数型プログラミングの特徴

Page 13: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

13

関数型プログラミングの特徴

関数の地位 -- first-class object としての関数

関数は、他のすべての値と同じ地位を持つ関数は、式の値となり得る関数を引数として渡すことができる関数を、データ構造の中に収めることも

出来る

25

関数型プログラミングの特徴

注: first-class object

第一級オブジェクト(一等値)プログラミング言語において、

計算対象となるデータ(値)のこと

26

Page 14: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

14

関数型プログラミングの特徴

ラムダ式/ラムダ計算 (lambda calculus)

関数を定義し、関数適用を繰返すことにより、計算を行う

ラムダ計算は、関数型プログラミングの理論的基盤である

27

1930s

Alonzo Church develops the lambda calculus, a simple but powerful theory of functions.

28

関数型プログラミングの歴史

Page 15: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

15

1950s

John McCarthy develops Lisp, the first functional language, with some influences from the lambda calculus, but retaining variable assignments.

29

関数型プログラミングの歴史

1960s

Peter Landin develops ISWIM, the first pure functional language, based strongly on the lambda calculus, with no assignments.

30

関数型プログラミングの歴史

Page 16: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

16

1970s

John Backus develops FP, a functional language that emphasizes higher-order functions and reasoning about programs.

31

関数型プログラミングの歴史

1970s

Robin Milner and others develop ML, the first modern functional language, which introduced type inference and polymorphic types.

32

関数型プログラミングの歴史

Page 17: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

17

1970s -1980s

David Turner develops a number of lazy functional languages, culminating in the Miranda system.

33

関数型プログラミングの歴史

1987

An international committee of researchers initiates the development of Haskell, a standard lazy functional language.

34

関数型プログラミングの歴史

Page 18: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

18

1990s

Phil Wadler and others develop type classes and monads, two of the main innovations of Haskell.

35

関数型プログラミングの歴史

36

Page 19: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

19

Abstract word cloud for Functional programming

37

BackusのTuring 賞

John Backus は言語設計者 Fortran, BNF, etc.

Turing 賞受賞(1977)

38

Page 20: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

20

BackusのTuring 賞

Turing 賞講演“Can Programming Be Liberated From the von Neumann Style?”,

(1977 Turing Award Lecture)

関数型言語は命令型言語に優る 関数型言語の方が、推論しやすい 並列性があり、より効率的 代数的法則 プログラムに関する推論 コンパイラの最適化

39

プログラムに関する推論

プログラムの正しさの証明 プログラムが依存していること全てを考慮す

る必要

関数型プログラムにおいては どんなデータ構造への依存もexplicit

従って 関数型プログラムに関する推論は易しい

40

Page 21: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

21

比較: C によるquicksort

41

Haskell によるQuicksort

非常に簡潔に書ける

これで全部 代入無し、ソート済みリストに関する式を書くのみ 配列インデックス無し、ポインタ無し、メモリ管理

なし、…42

Page 22: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

22

あるcase study

米国の海軍のあるセンターでのプログラム実験 別々のチームが別々の言語でプログラムする 結果にはかなりの違いがあった

不完全であったり実行できないものもあった 評価に携(たずさ)わった人の中には、プログラムを見たとき、

Haskellプログラムが完成していたことにかなり驚いた人がいた。というのもHaskellは抽象度の高い、仕様記述言語であると考えていたからである。 43

関数型 vs オブジェクト指向

44

Page 23: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

23

45

関数型 vs オブジェクト指向

ラムダ式 (lambda calculus)

関数をλ 式で表すsq(x) = x * x

sq = λx.* x x

46

関数値の計算方法=関数本体 (body)

引数がxであることを示す

Page 24: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

24

ラムダ式 (lambda calculus)

関数適用と関数抽象M、Nがλ式のとき MN を 関数適用 (application)という関数の呼出しに相当する

λx.M を 関数抽象 (abstraction) 、(またはラムダ抽象)という関数の定義に相当する

4747

ラムダ式 (lambda calculus)

λ式の定義 (M、Nはλ式とする) 変数はλ式である 関数適用 (MN) は λ式である 関数抽象 (λx.M) はλ式である

※ 紛(まぎ)らわしくない場合は、括弧は適宜省略できるものとする

48

Page 25: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

25

ラムダ計算 (lambda calculus)

λ計算とは関数の定義と実行を抽象化した計

算体系 λ式の「簡約」により、計算を行う λ算法ともいう

4949

ラムダ計算 (lambda calculus)

束縛変数 (bound variable)

式Mに出現する変数 xは、抽象化λx.Mにより束縛 (bind)されるという

(例) λx.+ x 1

x が仮引数として宣言されたことを

意味する

50

Page 26: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

26

ラムダ計算 (lambda calculus)

自由変数 (free variable) 束縛変数ではない変数

(例1) λx.+ x y

xは束縛変数であるが、yは自由変数である

51

ラムダ計算 (lambda calculus)

(例) g(x,y) = a * x * y では、

a が自由変数で x, yが束縛変数⇒ g = λx.λy. * * a x y

g(x) = a * x * y であるとすると、

yは aと同様の自由変数である⇒ g = λx. * * a x y

52

Page 27: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

27

ラムダ計算 (lambda calculus)

λ式の簡約(reduction) α変換 β簡約 η変換

53

ラムダ計算 (lambda calculus)

λ計算の用途 計算の意味論 計算可能性理論 型理論

λ式 / λ計算では、全ての「計算可能な関数」を表現し、計算することができる

54

Page 28: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

28

Scheme

以降は、LISPの方言である Schemeを題材とする Lispの中核部分を提供 比較的小規模

55Gerald Jay SussmanGuy L. Steele Jr.

Scheme

なぜ Lispなのか 最も早く開発された言語の一つ 1958 McCarthyにより設計された Fortranに次いで古い

再帰、first-class objectとしての関数、ガベッジコレクション、形式的言語定義などを最初に実現

統合プログラミング環境の先駆け

56

Page 29: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

29

Scheme

LISPの弱点 あまりに斬新な構文である "Lots of Irritating, Silly Parentheses“

LISPの実現が非効率であった(以前は)非常に計算が遅かった

57

Scheme

Schemeは、会話形式で動作する Schemeに対して、二種類の対話を考

える評価すべき式を与える名前を値で束縛する

Schemeは、評価した結果を表示する

58

Page 30: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

30

Scheme

59

> 3.14159

3.14159

> (define pi 3.14159)

pi

> pi

3.14159

プロンプト

結果表示

人が入力

名前を値で束縛

Scheme

式 括弧の中に、演算子とオペランドを前

置記法により記述する

EOP は、E1・・Ek に適用される演算子 E1・・Ek を評価してから、EOP を適用

する

60

(EOP E1 ・・・ Ek)

Page 31: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

31

Scheme

61

> (+ 2 3 5)

10

> (+ 4 (* 5 7))

39

> (acos -1)

3.141592653589793

Scheme

引用 式をデータとして扱う 引用された項目を評価したら、その

値はそれ自身となる 次の2通りの書き方がある

62

(quote <item>)'<item>

Page 32: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

32

Scheme

引用されていない名前は、ある値に束縛されている 下の pi は 変数名である

引用すると、綴りとして扱える

63

> pi3.14159

> (quote pi)pi

Scheme

64

> (define f *)f

> (f 2 3)6

> (define f '*)f

> (f 2 3)ERROR: Bad procedure *

乗算関数

綴り「*」を表す記号

Page 33: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

33

Scheme

関数定義 関数定義の構文

ラムダ式の構文は

65

(define <fname> <lambda-expr>)

関数名 ラムダ式

(lambda ( <param> ) <expr>)

仮引数 式 (本体)

Scheme

66

> (define square (lambda(x) (* x x)) )

square

> (square 5)

25

Page 34: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

34

Scheme

は、次の defineと同じ構造

λx.*xx というλ式(関数) と、 3.14159という実数が、同じ立場

67

(define square (lambda(x) (* x x)) )

(define pi 3.14159)

Scheme

条件式 条件式の形式 (1)

"if P then E1 else E2"Pが真ならばE1を評価し、偽ならばE2を評価する

68

(if P E1 E2 )

Page 35: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

35

Scheme

条件式の形式 (2)

"if P1 then E1 else if ・・・else if Pk then Ek else Ek+1"

69

(cond (P1 E1 )

・・・

(Pk Ek )

(else Ek+1 ) )

Scheme

条件式の利用例 = 再帰

70

nの階乗を求める関数?

Page 36: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

36

Scheme

条件式の利用例 = 再帰

71

(define fact(lambda (n)(if (<= n 1) 1

(* n (fact (- n 1))) )))

nの階乗を求める関数

Quiz Time!

2019/6/27 72

Page 37: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

37

練習問題

フィボナッチ数を求める関数 fibを、定義せよ

fib(0) = 0

fib(1) = 1

fib(n) = fib(n-1) + fib(n-2)

(ただし、n≧2)

73

解答

(define fib

(lambda (n)

(cond ((<= n 0) 0)

((= n 1) 1)

(else (+ (fib(- n 1))

(fib(- n 2))

)) )))

74

Page 38: 2019-L11-Functional Programming Languages-20190627-studentsstap.ait.kyushu-u.ac.jp/~zhao/course/2019/2019-L11... · 2019-06-27 · ppp pIp pxp pIp pjp pYp=py w º W ¹ppp pIp pxp

2019/6/27

38

解答 (別解)

(define fib

(lambda (n)

(if (<= n 0) 0

(if (= n 1) 1

(+ (fib(- n 1))

(fib(- n 2)) )) )))

75

まとめ

In functional programming:

The basic method of computation is the application of functions to arguments

A functional language is one that supports and encourages the functional style

76