SlideShare a Scribd company logo
Functional Way
自己紹介: lagénorhynque
(defprofile lagénorhynque [Kent OHASHI]
:github/twitter @lagenorhynque
:company 株式会社オプト
:languages [Clojure Haskell Python Scala Go
English français Deutsch русский]
:interests [プログラミング 語学 数学])
「フィボナッチ数」( )の計算を例にFibonacci number
関数型プログラミングの基本的な概念を紹介
1. 再帰(recursion)
2. 末尾再帰(tail recursion)
3. 高階関数(higher-order function)
4. 遅延評価(lazy evaluation)
フィボナッチ数
番目のフィボナッチ数 は、以下のように定義される。i Fi
F0
F1
Fi
=
=
=
0
1
+ , i ≥ 2Fi−2 Fi−1
と続き、0, 1, 1, 2, 3, 5, 8, 13, 21, 34, . . .
直前の2項の和が次の項になっている。
0. ループ
手続き型( )言語の基本パターンprocedural
# Python
def fibonacci(i):
a, b = 0, 1
for n in range(i):
a, b = b, a + b
return a
副作用( )
命令型( )
side e ect
imperative
変数やループ構造が目立ち、数学的な定義(プログラムの仕様)との関
係が分かりづらい
登場する変数が多くなったり、処理が複雑になったりすると、状態の
変化をたどるのが困難になりうる
1. 再帰 ( )recursion
関数型( )言語の基本パターンfunctional
-- Haskell
fibonacci1 :: Int -> Integer
fibonacci1 0 = 0
fibonacci1 1 = 1
fibonacci1 i = fibonacci1 (i - 2) + fibonacci1 (i - 1)
;; Clojure
(defn fibonacci1 [i]
(cond
(= i 0) 0N
(= i 1) 1N
:else (+ (fibonacci1 (- i 2)) (fibonacci1 (- i 1)))))
パターンマッチング( )
宣言型( )
参照透過性( )
pattern matching
declarative
referential transparency
数学的な再帰的定義をほぼそのまま表現した、シンプルなコード
可変状態がないため状態の変化を管理する必要がなくなり、並列/並
行処理として実行するのも比較的容易
関数呼出しの繰り返しによりスタックオーバーフローが発生する可能
性がある
フィボナッチ数の場合、同一の計算が繰り返されて計算量が指数的に
増大してしまう→メモ化( )を検討memoization
2. 末尾再帰 ( )tail recursion
関数内部で最後に実行される処理が再帰呼出しになっている再帰
-- Haskell
fibonacci2 :: Int -> Integer
fibonacci2 i = fib i 0 1
where
fib 0 a _ = a
fib n a b = fib (n - 1) b (a + b)
;; Clojure
(defn fibonacci2 [i]
(letfn [(fib [n a b]
(if (zero? n)
a
(recur (dec n) b (+ a b))))]
(fib i 0N 1N)))
多くの関数型言語では末尾再帰関数が末尾呼出し最適化(tail call
optimization)により命令型のループと同等の処理に変換され、スタ
ックオーバーフローが防止できる
コードの処理内容も命令型ループによく似ている
3. 高階関数 ( )higher-order function
引数として関数を受け取る、または戻り値として関数を返す関数
-- Haskell
fibonacci3 :: Int -> Integer
fibonacci3 i = fst $ foldl' fib (0, 1) [1..i]
where
fib (a, b) _ = (b, a + b)
;; Clojure
(defn fibonacci3 [i]
(letfn [(fib [[a b] _]
[b (+ a b)])]
(first (reduce fib [0N 1N] (range 0 i)))))
典型的な繰り返し処理は抽象化されたライブラリの高階関数に任せ、
固有のロジックを持った関数の実装に集中することで、効率良くコー
ディングすることができ、コードの可読性も向上する
オブジェクト指向プログラミングのデザインパターンの多くは高階関
数によって同等の目的を果たせる
4. 遅延評価 ( )lazy evaluation
式の評価を計算で必要になるまで遅らせる評価戦略
cf. 先行評価( )eager evaluation
-- Haskell
fibonacci4 :: Int -> Integer
fibonacci4 i = fibs !! i
where
fibs = map fst $ iterate ((a, b) -> (b, a + b)) (0, 1)
;; Clojure
(defn fibonacci4 [i]
(let [fibs (map first (iterate (fn [[a b]] [b (+ a b)]) [0N 1N]))]
(nth fibs i)))
-- Haskell
fibonacci5 :: Int -> Integer
fibonacci5 i = fibs !! i
where
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
;; Clojure
(defn fibonacci5 [i]
(letfn [(fibs [a b] (cons a (lazy-seq (fibs b (+ a b)))))]
(nth (fibs 0N 1N) i)))
Haskellでは遅延評価がデフォルトの評価戦略
Clojureは先行評価が基本だが、遅延評価されるシーケンス(遅延シー
ケンス)が利用できる
特に巨大なデータ構造や無限に続くデータ構造を扱う場合に、シンプ
ルな定義と効率を両立させることができる
Further Reading
Haskell
『プログラミングHaskell』
『すごいHaskellたのしく学ぼう!』
『関数プログラミング実践入門』
Clojure
『プログラミングClojure』
Exploring Clojure with Factorial Computation
Scala
『Scalaスケーラブルプログラミング』
『Scala関数型デザイン&プログラミング』
Erlang
『すごいErlangゆかいに学ぼう!』
Elixir
『プログラミングElixir』
OCaml
『プログラミングの基礎』
cf. 今回の発表の元ネタ: BasicsOfFunctionalProgramming.md

More Related Content

PDF
おいしいLisp
PDF
From Java To Clojure
PDF
From JS To CLJS
PDF
C++14 Overview
PPTX
大人のお型付け
PDF
F#入門 ~関数プログラミングとは何か~
PDF
C++ lecture-2
おいしいLisp
From Java To Clojure
From JS To CLJS
C++14 Overview
大人のお型付け
F#入門 ~関数プログラミングとは何か~
C++ lecture-2

What's hot (20)

PDF
並行プログラミングと継続モナド
PPTX
ナウなヤングにバカうけのイカしたタグ付き共用体
PPTX
Visual C++で使えるC++11
PDF
Fork/Join Framework。そしてLambdaへ。
PPTX
【java8 勉強会】 怖くない!ラムダ式, Stream API
PDF
これからの「言語」の話をしよう ―― 未来を生きるためのツール
PPT
言語処理系入門4
PDF
Java SE 8 lambdaで変わる プログラミングスタイル
PDF
組み込みでこそC++を使う10の理由
PDF
JavaScript 講習会 #1
PDF
C++ lecture-0
PPTX
Scalamacrosについて
PDF
F#によるFunctional Programming入門
PPT
言語処理系入門€5
PDF
C++コンパイラ GCCとClangからのメッセージをお読みください
PDF
60分で体験する Stream / Lambda
 ハンズオン
PDF
Good Parts of PHP and the UNIX Philosophy
PDF
ちょっと詳しくJavaScript 第2回【関数と引数】
PDF
Python で munin plugin を書いてみる
並行プログラミングと継続モナド
ナウなヤングにバカうけのイカしたタグ付き共用体
Visual C++で使えるC++11
Fork/Join Framework。そしてLambdaへ。
【java8 勉強会】 怖くない!ラムダ式, Stream API
これからの「言語」の話をしよう ―― 未来を生きるためのツール
言語処理系入門4
Java SE 8 lambdaで変わる プログラミングスタイル
組み込みでこそC++を使う10の理由
JavaScript 講習会 #1
C++ lecture-0
Scalamacrosについて
F#によるFunctional Programming入門
言語処理系入門€5
C++コンパイラ GCCとClangからのメッセージをお読みください
60分で体験する Stream / Lambda
 ハンズオン
Good Parts of PHP and the UNIX Philosophy
ちょっと詳しくJavaScript 第2回【関数と引数】
Python で munin plugin を書いてみる
Ad

Viewers also liked (14)

PDF
MP in Haskell
PDF
From Java To Clojure (English version)
PDF
MP in Scala
PPTX
Clojure座談会 #1 LT 独自コレクションを定義しよう
PPTX
Rプログラミング01 はじめの一歩
DOCX
Rデモ01_はじめの一歩2016
PDF
ロジカル・シンキング & システム設計・プログラミングについて
DOCX
Rデモ02_入出力編2016
DOCX
Rデモ03_データ分析編2016
PPTX
Rプログラミング02 データ入出力編
PDF
HTTP/2 in nginx(2016/3/11 社内勉強会)
PPTX
Rプログラミング03 データ分析編
PDF
ネットワーク概論 サーバの構築理論
PDF
Practical Phonetics (実践音声学)
MP in Haskell
From Java To Clojure (English version)
MP in Scala
Clojure座談会 #1 LT 独自コレクションを定義しよう
Rプログラミング01 はじめの一歩
Rデモ01_はじめの一歩2016
ロジカル・シンキング & システム設計・プログラミングについて
Rデモ02_入出力編2016
Rデモ03_データ分析編2016
Rプログラミング02 データ入出力編
HTTP/2 in nginx(2016/3/11 社内勉強会)
Rプログラミング03 データ分析編
ネットワーク概論 サーバの構築理論
Practical Phonetics (実践音声学)
Ad

Similar to Functional Way (20)

PDF
ALPSチュートリアル(4) Python入門
PDF
たのしい関数型
PDF
命令プログラミングから関数プログラミングへ
PPTX
やや関数型を意識した風Elixir/Phoenixご紹介
PPT
言語処理系入門€10
PPTX
Control.Arrow
PDF
Everyday Life with clojure.spec
PDF
研究生のためのC++ no.2
PDF
関数プログラミング入門
PDF
Rの高速化
PDF
たのしい高階関数
PDF
Subprocess no susume
PDF
関数型都市忘年会『はじめての函数型プログラミング』
KEY
あらためてPHP5.3
PDF
Lisp tutorial for Pythonista : Day 2
PDF
Haxeについて
PDF
Python勉強会4-制御構文とパッケージ
PDF
Pfi Seminar 2010 1 7
PDF
すごいHaskell読書会#1 in 大阪
PPTX
Polyphony の並列化
ALPSチュートリアル(4) Python入門
たのしい関数型
命令プログラミングから関数プログラミングへ
やや関数型を意識した風Elixir/Phoenixご紹介
言語処理系入門€10
Control.Arrow
Everyday Life with clojure.spec
研究生のためのC++ no.2
関数プログラミング入門
Rの高速化
たのしい高階関数
Subprocess no susume
関数型都市忘年会『はじめての函数型プログラミング』
あらためてPHP5.3
Lisp tutorial for Pythonista : Day 2
Haxeについて
Python勉強会4-制御構文とパッケージ
Pfi Seminar 2010 1 7
すごいHaskell読書会#1 in 大阪
Polyphony の並列化

More from Kent Ohashi (20)

PDF
関数型言語テイスティング: Haskell, Scala, Clojure, Elixirを比べて味わう関数型プログラミングの旨さ
PDF
純LISPから考える関数型言語のプリミティブ: Clojure, Elixir, Haskell, Scala
PDF
From Scala/Clojure to Kotlin
PDF
TDD with RDD: Clojure/LispのREPLで変わる開発体験
PDF
🐬の推し本紹介2024: 『脱・日本語なまり 英語(+α)実践音声学』
PDF
do Notation Equivalents in JVM languages: Scala, Kotlin, Clojure
PDF
map関数の内部実装から探るJVM言語のコレクション: Scala, Kotlin, Clojureコレクションの基本的な設計を理解しよう
PDF
Kotlin Meets Data-Oriented Programming: Kotlinで実践する「データ指向プログラミング」
PDF
RDBでのツリー表現入門2024
PDF
ミュータビリティとイミュータビリティの狭間: 関数型言語使いから見たKotlinコレクション
PDF
インターフェース定義言語から学ぶモダンなWeb API方式: REST, GraphQL, gRPC
PDF
Team Geek Revisited
PDF
Scala vs Clojure?: The Rise and Fall of Functional Languages in Opt Technologies
PDF
Clojureコレクションで探るimmutableでpersistentな世界
PDF
英語学習者のためのフランス語文法入門: フランス語完全理解(?)
PDF
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング
PDF
実用のための語源学入門
PDF
メタプログラミング入門
PDF
労働法の世界
PDF
Clojureで作る"simple"なDSL
関数型言語テイスティング: Haskell, Scala, Clojure, Elixirを比べて味わう関数型プログラミングの旨さ
純LISPから考える関数型言語のプリミティブ: Clojure, Elixir, Haskell, Scala
From Scala/Clojure to Kotlin
TDD with RDD: Clojure/LispのREPLで変わる開発体験
🐬の推し本紹介2024: 『脱・日本語なまり 英語(+α)実践音声学』
do Notation Equivalents in JVM languages: Scala, Kotlin, Clojure
map関数の内部実装から探るJVM言語のコレクション: Scala, Kotlin, Clojureコレクションの基本的な設計を理解しよう
Kotlin Meets Data-Oriented Programming: Kotlinで実践する「データ指向プログラミング」
RDBでのツリー表現入門2024
ミュータビリティとイミュータビリティの狭間: 関数型言語使いから見たKotlinコレクション
インターフェース定義言語から学ぶモダンなWeb API方式: REST, GraphQL, gRPC
Team Geek Revisited
Scala vs Clojure?: The Rise and Fall of Functional Languages in Opt Technologies
Clojureコレクションで探るimmutableでpersistentな世界
英語学習者のためのフランス語文法入門: フランス語完全理解(?)
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング
実用のための語源学入門
メタプログラミング入門
労働法の世界
Clojureで作る"simple"なDSL

Functional Way