SlideShare une entreprise Scribd logo
1  sur  37
Télécharger pour lire hors ligne
序文

関数型言語
.
1

序文
パラダイムの紹介
命令型の問題点

.
2

関数型の紹介

.
3

関数型のフィーチャー
第一級関数
再帰

.
4

関数型言語の問題点
状態がない
パーフォマンス
Daniel Perez

関数型言語

2013年12月20日

1 / 21
序文

パラダイムの紹介

パラダイム
.
パラダイムとは
.
プログラミングにおける「考え方」・「見方」
プログラムが状態を持つのか
プログラムはどう分割するか
クラスとオブジェクトで分けるか
プロシージャで分けるか
数学的な意味の関数で分けるか

.

副作用を許すか
などなど

Daniel Perez

関数型言語

2013年12月20日

2 / 21
序文

パラダイムの紹介

パラダイムについて
.
パラダイムのファクト
.
パラダイムは山ほどある
複数のパラダイムに対応するとが多い(マルチパラダイム)
どう使うかはプログラマーの自由
.
.
有名なパラダイム
.
命令型プログラミング (C, Fortran, Basicなど)
オブジェクト指向プログラミング (SmallTalk, Javaなど)
関数型プログラミング (Haskell, ML系など)
論理型プログラミング (Prolog, Datalogなど)
記号型プログラミング (Lisp系など)
.
Daniel Perez

関数型言語

2013年12月20日

3 / 21
序文

パラダイムの紹介

命令型プログラミング
.
原理
.
文が順番に実行されていく
文でプログラムの状態を変えていく
「何を」ではなく「どうやって」を中心に
一般的に複数のプロシージャで組まれる
.
§

¤

long f a c t o r i a l ( long n )
{

int i , r e s u l t = 1;
for ( i = 2; i <= n ; i < n )
{
r e s u l t *= i ;
}

return r e s u l t ;
}

¦

¥

命令型で階乗の計算
Daniel Perez

関数型言語

2013年12月20日

4 / 21
序文

パラダイムの紹介

オブジェクト指向プログラミング
.
原理
.
プログラムはオブジェクトの組み合わせ
オブジェクトはデータを持つ
オブジェクトはプロシージャを持つ
オブジェクトは一般的にクラスのインスタンス
.
§

¤

class I n t e g e r
def f a c t o r i a l
( 2 . upto self ) . i n j e c t ( & : * )
end
end
5. f a c t o r i a l

¦

¥

オブジェクト指向で階乗の計算
Daniel Perez

関数型言語

2013年12月20日

5 / 21
序文

命令型の問題点

命令型の問題点

.
サイド・エフェクト
.
プログラム状態が変わっていく
呼び出すタイミングや回数で影響を受ける
プログラムが分かりづらくなる
分散処理や自動化が難しくなる
.

Daniel Perez

関数型言語

2013年12月20日

6 / 21
関数型の紹介

関数型の基礎
関数型言語において, 数学的な意味での関数を扱う.
x! : N → N
{
1
(x = 0)
x! =
x · (x − 1)! (その他)

Daniel Perez

関数型言語

2013年12月20日

7 / 21
関数型の紹介

関数型の基礎
関数型言語において, 数学的な意味での関数を扱う.
x! : N → N
{
1
(x = 0)
x! =
x · (x − 1)! (その他)
§

¤

def f a c t ( x : Long ) : Long = x match {
case 0 => 1
case _ => x * f a c t ( x − 1)
}

¦

¥

Daniel Perez

関数型言語

2013年12月20日

7 / 21
関数型の紹介

数学的な意味での関数
.
性質
.
サイド・エフェクトがない
1つの入力に対して, 出力は絶対に変わらない
データが状態を持たない
参照透過性を持つ
.

Daniel Perez

関数型言語

2013年12月20日

8 / 21
関数型の紹介

関数型言語
関数型言語におけるプログラムは関数の組み合わせにすぎない
関数は入力を変えない. 新しい出力を生成する

Daniel Perez

関数型言語

2013年12月20日

9 / 21
関数型の紹介

関数型言語
関数型言語におけるプログラムは関数の組み合わせにすぎない
関数は入力を変えない. 新しい出力を生成する

Daniel Perez

関数型言語

2013年12月20日

9 / 21
関数型のフィーチャー

関数型のフィーチャー
命令型のフィーチャーだけで以上の書き方はほぼ不可能
関数型言語が新しい概念やフィーチャーを導入した
現在関数型言語でない言語でも取り入れられてるフィーチャー
もある

Daniel Perez

関数型言語

2013年12月20日

10 / 21
関数型のフィーチャー

関数型のフィーチャー
命令型のフィーチャーだけで以上の書き方はほぼ不可能
関数型言語が新しい概念やフィーチャーを導入した
現在関数型言語でない言語でも取り入れられてるフィーチャー
もある
.
フィーチャ一覧
.
第一級関数
高階関数
カリー化
関数の部分適用
遅延評価
などなど
.
Daniel Perez

関数型言語

2013年12月20日

10 / 21
関数型のフィーチャー

第一級関数

高階関数

関数は他の型と同じ扱いかたができる
関数を別の関数に渡すこともできる
§

¤

val l i s t = L i s t ( 1 , 2 , 3)
def square ( x : I n t ) = x * x
l i s t map square / / L i s t ( 1 , 4 , 9)
/ / postfixOps are l e f t a s s o c i a t i v e
l i s t map square foreach p r i n t l n / / 1n4  n9
/ / l i s t .map( square ) . foreach ( p r i n t l n )

¦

¥

Daniel Perez

関数型言語

2013年12月20日

11 / 21
関数型のフィーチャー

第一級関数

カリー化
非カリー化の関数
f : (X × Y ) → Z
カリー化の関数
f : X → (Y → Z)

Daniel Perez

関数型言語

2013年12月20日

12 / 21
関数型のフィーチャー

第一級関数

カリー化
非カリー化の関数
f : (X × Y ) → Z
カリー化の関数
f : X → (Y → Z)
§

¤

def w i t h W r i t e r ( f i l e : F i l e ) ( block : B u f f e r e d W r i t e r =>
Unit ) = . . . .
w i t h W r i t e r ( new F i l e ( " foobar " ) ) { out => out w r i t e "
foobar " }

¦

¥

Daniel Perez

関数型言語

2013年12月20日

12 / 21
関数型のフィーチャー

第一級関数

部分適用
関数が関数を返す
f : X → (Y → Z)
⇒∀ x ∈ X, f (x) ∈ Z Y

Daniel Perez

関数型言語

2013年12月20日

13 / 21
関数型のフィーチャー

第一級関数

部分適用
関数が関数を返す
f : X → (Y → Z)
⇒∀ x ∈ X, f (x) ∈ Z Y
§

¤

def w i t h W r i t e r ( f i l e : F i l e ) ( block : B u f f e r e d W r i t e r =>
Unit ) = . . . .

val f o o W r i t e r = w i t h W r i t e r ( new F i l e ( " foo " ) )
f o o W r i t e r { out => out p r i n t l n " foobar " }
f o o W r i t e r { out => out p r i n t l n " barbaz " }
¦

¥

Daniel Perez

関数型言語

2013年12月20日

13 / 21
関数型のフィーチャー

再帰

再帰の紹介
.
再帰を使う理由
.
状態が変わらない
→for(int i = 0; i < N; i++)は書けない
.

Daniel Perez

関数型言語

2013年12月20日

14 / 21
関数型のフィーチャー

再帰

再帰の紹介
.
再帰を使う理由
.
状態が変わらない
→for(int i = 0; i < N; i++)は書けない
命令型言語でよく使われているループは基本的に使えない
.

Daniel Perez

関数型言語

2013年12月20日

14 / 21
関数型のフィーチャー

再帰

再帰の紹介
.
再帰を使う理由
.
状態が変わらない
→for(int i = 0; i < N; i++)は書けない
命令型言語でよく使われているループは基本的に使えない
代わりに再帰的に定義することが一般的
.

Daniel Perez

関数型言語

2013年12月20日

14 / 21
関数型のフィーチャー

再帰

再帰の紹介
.
再帰を使う理由
.
状態が変わらない
→for(int i = 0; i < N; i++)は書けない
命令型言語でよく使われているループは基本的に使えない
代わりに再帰的に定義することが一般的
.
.
再帰の基本
.
基底段階: ここまで来たら関数を止める
帰納段階: 処理して, 再帰的に呼び出す段階
.

Daniel Perez

関数型言語

2013年12月20日

14 / 21
関数型のフィーチャー

再帰

再帰の例
.
階乗
.

.
§

{
1
(x = 0)
x! =
x · (x − 1)! (その他)

¤

def f a c t ( x : Long ) : Long = x match {
case 0 => 1
case _ => x * f a c t ( x − 1)
}

¦

¥

Daniel Perez

関数型言語

2013年12月20日

15 / 21
関数型のフィーチャー

再帰

再帰の例
.
drop関数
.
drop(2, [1, 2, 3, 4])= [3, 4]
{
{a1 , · · · , an }
(x = 0)
f (x, {a1 , · · · , an }) =
f ((x − 1), {a2 , · · · , an }) (x > 0)
.

Daniel Perez

関数型言語

2013年12月20日

16 / 21
関数型のフィーチャー

再帰

再帰の例
.
drop関数
.
drop(2, [1, 2, 3, 4])= [3, 4]
{
{a1 , · · · , an }
(x = 0)
f (x, {a1 , · · · , an }) =
f ((x − 1), {a2 , · · · , an }) (x > 0)
.
§

¦

¤

def drop [ A ] ( n : I n t , l i s t : L i s t [ A ] ) : L i s t [ A ] = n match {
case 0 => l i s t
case _ => drop ( n − 1 , l i s t . t a i l )

Daniel Perez

関数型言語

2013年12月20日

¥

16 / 21
関数型のフィーチャー

再帰

再帰の例
.
map関数
.
map(f, [1, 2, 3])= [f(1), f(2), f(3)]
S, T は任意の集合
X = {a1 , · · · , an } ⊂ S

.

m : TS × X → Y ⊂ T
{
∅
m(f, {a1 , · · · , an }) =
∪
{f (a1 )} m(f, {a2 , · · · , an })

Daniel Perez

関数型言語

(X = ∅)
(その他)

2013年12月20日

17 / 21
関数型のフィーチャー

再帰

再帰の例
.
map関数
.
map(f, [1, 2, 3])= [f(1), f(2), f(3)]
S, T は任意の集合
X = {a1 , · · · , an } ⊂ S
m : TS × X → Y ⊂ T
{
∅
m(f, {a1 , · · · , an }) =
∪
{f (a1 )} m(f, {a2 , · · · , an })

.
§

(X = ∅)
(その他)

¤

def map[ A , B ] ( f : A => B , l i s t : L i s t [ A ] ) : L i s t [ B ] = l i s t match {
case N i l
=> N i l
case head : : t a i l => f ( head ) : : map( f , t a i l )
}

¦

¥
Daniel Perez

関数型言語

2013年12月20日

17 / 21
関数型のフィーチャー

再帰

名前呼び (Call by name)
関数呼び出し時に結果まだ評価しなくて良い
関数内で始めて値を使う時に評価する

Daniel Perez

関数型言語

2013年12月20日

18 / 21
関数型のフィーチャー

再帰

名前呼び (Call by name)
§
¦

関数呼び出し時に結果まだ評価しなくて良い
関数内で始めて値を使う時に評価する

¤

def f = { p r i n t l n ( " c a l l f " ) ; 1 }

Daniel Perez

関数型言語

¥

2013年12月20日

18 / 21
関数型のフィーチャー

再帰

名前呼び (Call by name)
§
¦
§

関数呼び出し時に結果まだ評価しなくて良い
関数内で始めて値を使う時に評価する

¤

def f = { p r i n t l n ( " c a l l f " ) ; 1 }
def fByValue ( n : I n t ) = {

¥

¤

p r i n t l n ( " c a l l i n g fByValue " )
p r i n t l n ( s " x1 = $n" )
p r i n t l n ( s " x2 = $n" )
}
fByValue ( f )

¦

¥

Daniel Perez

関数型言語

2013年12月20日

18 / 21
関数型のフィーチャー

再帰

名前呼び (Call by name)
§
¦
§

関数呼び出し時に結果まだ評価しなくて良い
関数内で始めて値を使う時に評価する

¤

def f = { p r i n t l n ( " c a l l f " ) ; 1 }
def fByValue ( n : I n t ) = {

¤§

p r i n t l n ( " c a l l i n g fByValue " )
p r i n t l n ( s " x1 = $n" )
p r i n t l n ( s " x2 = $n" )

def fByName ( n : => I n t ) = {
p r i n t l n ( " c a l l i n g fByName" )
p r i n t l n ( s " x1 = $n" )
p r i n t l n ( s " x2 = $n" )

}
fByValue ( f )

¦

}
fByName ( f )

¥¦

Daniel Perez

¥
¤

関数型言語

¥

2013年12月20日

18 / 21
関数型のフィーチャー

再帰

名前呼び (Call by name)
§
¦
§

関数呼び出し時に結果まだ評価しなくて良い
関数内で始めて値を使う時に評価する

def fByValue ( n : I n t ) = {

¤§

p r i n t l n ( " c a l l i n g fByValue " )
p r i n t l n ( s " x1 = $n" )
p r i n t l n ( s " x2 = $n" )

call f
c a l l i n g fByValue
x1 = 1
x2 = 1

¦

¥
¤

def fByName ( n : => I n t ) = {
p r i n t l n ( " c a l l i n g fByName" )
p r i n t l n ( s " x1 = $n" )
p r i n t l n ( s " x2 = $n" )

}
fByValue ( f )

¦
§

¤

def f = { p r i n t l n ( " c a l l f " ) ; 1 }

}
fByName ( f )

¥¦
¤

¥

¥
Daniel Perez

関数型言語

2013年12月20日

18 / 21
関数型のフィーチャー

再帰

名前呼び (Call by name)
§
¦
§

関数呼び出し時に結果まだ評価しなくて良い
関数内で始めて値を使う時に評価する

def fByValue ( n : I n t ) = {

¤§

p r i n t l n ( " c a l l i n g fByValue " )
p r i n t l n ( s " x1 = $n" )
p r i n t l n ( s " x2 = $n" )

call f
c a l l i n g fByValue
x1 = 1
x2 = 1

¦

def fByName ( n : => I n t ) = {

}
fByName ( f )

¥¦
¤§

¥¦
Daniel Perez

¥
¤

p r i n t l n ( " c a l l i n g fByName" )
p r i n t l n ( s " x1 = $n" )
p r i n t l n ( s " x2 = $n" )

}
fByValue ( f )

¦
§

¤

def f = { p r i n t l n ( " c a l l f " ) ; 1 }

関数型言語

c a l l i n g fByName
call f
x1 = 1
call f
x2 = 1

¥
¤

¥
2013年12月20日

18 / 21
関数型のフィーチャー

再帰

遅延評価 (Lazy evaluation)

値が必要になった時のみ評価される
Scalaではlazyで明示的に使う
§

¤

object DB {
lazy val connection = . . .
}

¦
§

def f i b : Stream [ I n t ] = 0 # : : f i b . scanLeft ( 1 ) { _ + _ }

¥
¤

f i b take 10 t o L i s t
¦

¥

Daniel Perez

関数型言語

2013年12月20日

19 / 21
関数型言語の問題点

状態がない

状態がない
.
問題
.
実際作るほとんどのものにおいて, 何かしら状態を持つ
データベースのモデル
ユーザーのセッション

.

参照透過性と状態を両立させることが難しい

Daniel Perez

関数型言語

2013年12月20日

20 / 21
関数型言語の問題点

状態がない

状態がない
.
問題
.
実際作るほとんどのものにおいて, 何かしら状態を持つ
データベースのモデル
ユーザーのセッション

.

参照透過性と状態を両立させることが難しい

.
解決
.
参照透過性を部分的になくす
モナドを使う
.

Daniel Perez

関数型言語

2013年12月20日

20 / 21
関数型言語の問題点

パーフォマンス

パーフォマンス

ハードウェアがミュータブルのデータに向いている
C言語の配列の読み・書き込みは非常に速い

コンパイル時に最適化してもその性能に近づくことが難しい

Daniel Perez

関数型言語

2013年12月20日

21 / 21

Contenu connexe

En vedette

Erlangを触ってみた
Erlangを触ってみたErlangを触ってみた
Erlangを触ってみたYoichi Toyota
 
GHC 6.12.1 マルチコア対応ランタイムシステムについて
GHC 6.12.1 マルチコア対応ランタイムシステムについてGHC 6.12.1 マルチコア対応ランタイムシステムについて
GHC 6.12.1 マルチコア対応ランタイムシステムについてMitsutoshi Aoe
 
F#で学ぶ関数プログラミング入門?
F#で学ぶ関数プログラミング入門?F#で学ぶ関数プログラミング入門?
F#で学ぶ関数プログラミング入門?pocketberserker
 
関数型言語初心者の俺がF#触ってみた
関数型言語初心者の俺がF#触ってみた関数型言語初心者の俺がF#触ってみた
関数型言語初心者の俺がF#触ってみたTakashi Nishisaki
 
第一回関数型言語勉強会 大阪
第一回関数型言語勉強会 大阪第一回関数型言語勉強会 大阪
第一回関数型言語勉強会 大阪Naoki Kitora
 
FP習熟度レベルとFSharpxのIteratee
FP習熟度レベルとFSharpxのIterateeFP習熟度レベルとFSharpxのIteratee
FP習熟度レベルとFSharpxのIterateepocketberserker
 
Pythonista による Pythonista のための Scala 紹介 in BPStudy #49
Pythonista による Pythonista のための Scala 紹介 in BPStudy #49Pythonista による Pythonista のための Scala 紹介 in BPStudy #49
Pythonista による Pythonista のための Scala 紹介 in BPStudy #49shoma h
 
Katagaitai CTF勉強会 #4 Crypto
Katagaitai CTF勉強会 #4 CryptoKatagaitai CTF勉強会 #4 Crypto
Katagaitai CTF勉強会 #4 Cryptotrmr
 
これから Haskell を書くにあたって
これから Haskell を書くにあたってこれから Haskell を書くにあたって
これから Haskell を書くにあたってTsuyoshi Matsudate
 
120901fp key
120901fp key120901fp key
120901fp keyksknac
 
純粋関数型アルゴリズム入門
純粋関数型アルゴリズム入門純粋関数型アルゴリズム入門
純粋関数型アルゴリズム入門Kimikazu Kato
 
関数型言語とオブジェクト指向言語(序章)
関数型言語とオブジェクト指向言語(序章)関数型言語とオブジェクト指向言語(序章)
関数型言語とオブジェクト指向言語(序章)tadaaki hayashi
 
データベース入門3
データベース入門3データベース入門3
データベース入門3tadaaki hayashi
 
関数プログラミング入門
関数プログラミング入門関数プログラミング入門
関数プログラミング入門Hideyuki Tanaka
 
磯野ー!関数型言語やろうぜー!
磯野ー!関数型言語やろうぜー!磯野ー!関数型言語やろうぜー!
磯野ー!関数型言語やろうぜー!Ra Zon
 
Scalaで学ぶ関数型言語超入門
Scalaで学ぶ関数型言語超入門Scalaで学ぶ関数型言語超入門
Scalaで学ぶ関数型言語超入門yujiro_t
 

En vedette (20)

Erlangを触ってみた
Erlangを触ってみたErlangを触ってみた
Erlangを触ってみた
 
Erlang
ErlangErlang
Erlang
 
GHC 6.12.1 マルチコア対応ランタイムシステムについて
GHC 6.12.1 マルチコア対応ランタイムシステムについてGHC 6.12.1 マルチコア対応ランタイムシステムについて
GHC 6.12.1 マルチコア対応ランタイムシステムについて
 
Yesod(at FPM2012)
Yesod(at FPM2012)Yesod(at FPM2012)
Yesod(at FPM2012)
 
F#で学ぶ関数プログラミング入門?
F#で学ぶ関数プログラミング入門?F#で学ぶ関数プログラミング入門?
F#で学ぶ関数プログラミング入門?
 
関数型言語初心者の俺がF#触ってみた
関数型言語初心者の俺がF#触ってみた関数型言語初心者の俺がF#触ってみた
関数型言語初心者の俺がF#触ってみた
 
第一回関数型言語勉強会 大阪
第一回関数型言語勉強会 大阪第一回関数型言語勉強会 大阪
第一回関数型言語勉強会 大阪
 
FP習熟度レベルとFSharpxのIteratee
FP習熟度レベルとFSharpxのIterateeFP習熟度レベルとFSharpxのIteratee
FP習熟度レベルとFSharpxのIteratee
 
Pythonista による Pythonista のための Scala 紹介 in BPStudy #49
Pythonista による Pythonista のための Scala 紹介 in BPStudy #49Pythonista による Pythonista のための Scala 紹介 in BPStudy #49
Pythonista による Pythonista のための Scala 紹介 in BPStudy #49
 
Katagaitai CTF勉強会 #4 Crypto
Katagaitai CTF勉強会 #4 CryptoKatagaitai CTF勉強会 #4 Crypto
Katagaitai CTF勉強会 #4 Crypto
 
これから Haskell を書くにあたって
これから Haskell を書くにあたってこれから Haskell を書くにあたって
これから Haskell を書くにあたって
 
JSer Class #1
JSer Class #1JSer Class #1
JSer Class #1
 
120901fp key
120901fp key120901fp key
120901fp key
 
純粋関数型アルゴリズム入門
純粋関数型アルゴリズム入門純粋関数型アルゴリズム入門
純粋関数型アルゴリズム入門
 
関数型言語とオブジェクト指向言語(序章)
関数型言語とオブジェクト指向言語(序章)関数型言語とオブジェクト指向言語(序章)
関数型言語とオブジェクト指向言語(序章)
 
データベース入門3
データベース入門3データベース入門3
データベース入門3
 
関数プログラミング入門
関数プログラミング入門関数プログラミング入門
関数プログラミング入門
 
Haskell超入門 Part.1
Haskell超入門 Part.1Haskell超入門 Part.1
Haskell超入門 Part.1
 
磯野ー!関数型言語やろうぜー!
磯野ー!関数型言語やろうぜー!磯野ー!関数型言語やろうぜー!
磯野ー!関数型言語やろうぜー!
 
Scalaで学ぶ関数型言語超入門
Scalaで学ぶ関数型言語超入門Scalaで学ぶ関数型言語超入門
Scalaで学ぶ関数型言語超入門
 

関数型軽い紹介