SlideShare uma empresa Scribd logo
1 de 102
Baixar para ler offline
関数型指向
Python
LLまつり2013 / @esehara
お前
誰だ
Esehara Shigeo(29)
言語:Python
OS:Ubuntu + Amesome(タイル型)
好きなMonad: Maybe
気になる言語: Prolog
所属: 株式会社マリーチ
このスライドは以下に、
既にアップされているので
スライドを手元でみたいときは
http://www.slideshare.net/esehara/
から見てください
ところで
皆さんに
質問が
あります
関数型言語
使って
ますか?
そもそも
「関数型言語」
ってなんですか?
(eq?
functional lisp)
=> #t / #f ?
(eq? functional lisp)
『計算機プログラムの構造と解釈』
特徴のもっとも著しいのは
プロセスの手続き
(procedures)
というLispによる記述自体が
Lispデータとして表現, 処理出
来ることである.
(p. 2)
プロセスの手続き
というLispによる
記述……?
手続きって
関数型
と違うものなの?
抜き打ち調査
(eq?
functional
X_language)
ERROR:
Unbound
valiable:
functional
type
関数型言語 =
Maybe
BuzzWord
ここまで
前置き
なぜ関数型「指向」としたか
●ここでは「関数型言語」の正
確な定義については考えな
い
(定義的には透明参照性があり、その
ことによって副作用を封じ込める云々
があるが、そこまで厳密に考えると
Maybe Me = 死ぬ | 殺される)
正直、
OCaml Meeting
Proof Summitが
同日で助かった
なぜ関数型「指向」としたか
●そこで、あえて「関数型言語」とは別に
「プログラムの書き方」として「関数型
指向」を使う
→「関数型指向」と定義するものは、「関数を連鎖さ
せることによって、手続き=プロセスを記述する」に
着目をすることとする。
→数学的な意味での「関数」の意味と、Pascal以降
の「プログラム」的な意味での「関数」を分離する
Pythonでの例
from __future__ import print_function
one = lambda: 1
two = lambda: 2
to_list = lambda *fs: [f() for f in fs]
do = lambda *args: args[0](*args[1:])
do(print,
do(sum,
do(to_list, one, two)))
素直に書くと……
one = 1
two = 2
test_data = [one, two]
result_sum = sum(test_data)
print result_sum
ところで
皆さんに
質問が
あります
「代入」って
簡単ですか?
よくある代入の説明
変数は「箱」です。
代入は、変数という「箱」に
値を保管するということです。
よくある代入の説明
変数は「箱」です。
代入は、変数という「箱」に
値を保管するということです。
どういう
ことだ?
抜き打ちテスト
def test(origin_list):
result = origin_list
result[0] = "FooBar"
return result
a = [1, 2, 3]
# リストの最初を
# Foobarにする
print test(a)
# [1, 2, 3]を出したい
print a
[“Foobar”, 2, 3]
[“Foobar”, 2, 3]
結果
代入の難しさ
● 値渡しと参照渡しがある
● 「何が値渡し」か「何が参照
渡し」かは、言語の仕様に
よって変化する
真夏の怪談
「代入の恐怖」
あれは
某プロジェクトの
ことでした
プロジェクトは
PHPで
書かれて
いたんですよ……
フレームワークは
CakePHP
コントローラを
開いたら……
メソッド
2500行
あなたの隣にも、ほら……
代入の難しさ
● 代入は「データ」をとりあえずおいておく
場所として機能する
● そうすると、代入しまくってなんとかしよ
うとする
● 何も考えないとメソッドや関数が肥大化
する
代入の難しさ
「Object Calisthenics」
インスタンス
変数は二つまで
「関数」を意識する
● 細かく「関数」(or メソッド)に
することで、その操作が何を
目的にしているのかというの
を意識的に命名できる
例:Fizzbuzz
ルール
● 1..100の数が入力される
● 3で割り切れる数は”Fizz”
● 5で割り切れる数は”Buzz”
● 3と5で割り切れる数は”FizzBuzz”
● 上記に当てはまらない場合、数を返す
素直に書くと……
def fizzbuzz(x):
if x % 15 == 0:
return "FizzBuzz"
if x % 3 == 0:
return "Fizz"
if x % 5 == 0:
return "Buzz"
return x
for x in range(1, 100):
print fizzbuzz(x)
ここで
問題です
問題: lambda_fizzbuzz
from __future__ import print_function
def function_fizzbuzz(x):
#fizzとbuzzの関数を定義すること
#ただし、lambdaだけで定義せよ
return fizz(buzz(x))
[print(function_fizzbuzz(x)) for x in range(1,
100)]
lambda
とは
Pythonにおけるlambda
origin = lambda x: x
# <function __main__.<lambda>>
def _lambda(x):
return x
custom = _lambda
#要するにfunction objectを渡している
# >>> (lambda x: x * 2)(3)
# 6
考え方
● 出力結果の可能性は、入力された数, “Fizz”,
“Buzz”, “FizzBuzz”
● 結果は「数」か「文字」
● 「文字」の場合は、3で割り切れる、5で割り切れ
る、15で割り切れるときに出力する
● 15で割り切れる = 3で割り切れ、かつ5で割り切れる
● 3, 5 をフラグで管理し、3で割り切れるときは”Fizz”、
5で割り切れるときは”Buzz”に置換し、両方に当ては
まる場合は、二つをあわせる。
条件演算子を使おう
_buzz = lambda x: “” if x % 3 else “Buzz”
# ある値の後に “if” が入ると、
# あいだの値がFalseだと、else以降の値が
# 採用される
# ちなみに、Pythonは 0, “”, [], () を 判定すると
# False が返ってくるので、割り切れるときは
# False になると理解する
条件演算子を使おう
_fizz = lambda x: “” if x % 3 else “FIzz”
_buzz = lambda x: “” if x % 5 else “Buzz”
# 同じような式を省略できないのか
クロージャと
和解せよ
クロージャを使おう
変数のスコープは
ソースコード内の位置に
よって決定され
入れ子にされた関数は
外側のスコープで宣言された
変数にアクセスする
https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Closures
外側に
スコープが
ある変数?
クロージャを使おう
def closure(x):
def _function():
return x
return _function
one = closure(1)
print one()
lambda_closure = lambda x: lambda: x
two = lambda_closure(2)
print two()
クロージャを使おう
ポイント
●関数内部で定義された関
数は、その関数を定義しよ
うとしている関数に渡され
た引数を参照できる
クロージャを使おう
ポイント
●関数内部で定義された関
数は、その関数を定義しよ
うとしている関数に渡され
た引数を参照できる
お前は
何を
言っている
想像してごらん……
クロージャ関数は
「箱」である
想像してごらん……
クロージャ関数
「xって値を
この関数に入れておき
ましたので、呼び出せ
ば取り出せますよ」
あれ、この説明
どこかで……
よくある代入の説明
変数は「箱」です。
代入は、変数という「箱」に
値を保管するということです。
よくあるクロージャ関数の説明
クロージャ関数は「箱」です。
クロージャ関数は、
関数という「箱」に
値を保管するということです。
抜き打ちテスト
closure = lambda x: lambda: x
foo = closure([1, 2, 3])
print foo()
foo()[0] = "Foobar"
print foo()
あ、ここ代入で
やったところだ!
(by. 受験生)
[1, 2, 3]
[“Foobar”, 2, 3]
結果
「代入」は
何度でも
蘇る
変数が死んでも
第二、
第三の代入
が現れるだろう
「関数」を
渡していると
いって
油断するな
deepcopy
と和解せよ
from copy import deepcopy
closure = lambda x: lambda: deepcopy(x)
array = closure([1, 2, 3])
array()[0] = "Foobar"
print array()
[1, 2, 3]
結果
deepcopyと和解せよ
ポイント
●深いコピー(deep copy)は新たな複
合オブジェクトを作成し、その後元の
オブジェクト中に見つかったオブジェ
クトのコピーを挿入します。
http://docs.python.jp/2/library/copy.html?highlight=deepcopy
「似非原さん」
「先ほどから
色々と
説明して
いますが」
「lambda
fizzbuzz
進捗どうですか」
ウッ
問題: lambda_fizzbuzz
from __future__ import print_function
def function_fizzbuzz(x):
#fizzとbuzzの関数を定義すること
#ただし、lambdaだけで定義せよ
return fizz(buzz(x))
[print(function_fizzbuzz(x)) for x in range(1,
100)]
解答: lambda_fizzbuzz
from __future__ import print_function
_div_to_str = lambda x, y: lambda _x: "" if _x % x else y
_buzz = _div_to_str(5, "Buzz")
buzz = lambda x: [_buzz(x), x]
__fizz = _div_to_str(3, "Fizz")
_fizz = lambda x: [__fizz(x[1]) + x[0], x[1]]
fizz = lambda x: print(_fizz(x)[0]) if (_fizz(x)[0]) else
print(x[1])
fizzbuzz = lambda x: fizz(buzz(x))
[fizzbuzz(x) for x in range(1, 100)]
これが
lambdaの
力である
関数型指向
Python
LLまつり2013 / @esehara
関数型指向
Python
LLまつり2013 / @esehara
改め
Lambda型
指向Python
LLまつり2013 / @esehara
完
「似非原さん」
「先ほどから
色々と
説明して
いますが」
「プレゼンの
納期(20分)
どうですか」
ウッ
課題
decorator
と和解せよ
問題: decorator_fizzbuzz
from __future__ import print_function
@fizz
@buzz
def decorator_fizzbuzz(x):
pass
[print(decorator_fizzbuzz(x)) for x in range(1,
100)]
Pythonにおけるdecorator
PEP 318
Decorators for
Functions and Methods
Pythonにおけるdecorator
@dec2
@dec1
def func(arg1, arg2, ...):
pass
def func(arg1, arg2, ...):
pass
func = dec2(dec1(func))
例: lambda_fizzbuzz
fizzbuzz = lambda x: fizz(buzz(x))
例: decorator_fizzbuzz
decorator_fizzbuzz = fizz(buzz(func))
ご静聴
ありがとう
ございました
PyConの成功
心からお祈り
しています

Mais conteúdo relacionado

Mais procurados

これからの「言語」の話をしよう ―― 未来を生きるためのツール
これからの「言語」の話をしよう ―― 未来を生きるためのツールこれからの「言語」の話をしよう ―― 未来を生きるためのツール
これからの「言語」の話をしよう ―― 未来を生きるためのツールNobuhisa Koizumi
 
.NET系開発者から見たJava
.NET系開発者から見たJava.NET系開発者から見たJava
.NET系開発者から見たJavableis tift
 
Swift の3大プロトコルを眺めてみる #love_swift
Swift の3大プロトコルを眺めてみる #love_swiftSwift の3大プロトコルを眺めてみる #love_swift
Swift の3大プロトコルを眺めてみる #love_swiftTomohiro Kumagai
 
Python と型ヒント (Type Hints)
Python と型ヒント (Type Hints)Python と型ヒント (Type Hints)
Python と型ヒント (Type Hints)Tetsuya Morimoto
 
静的型付け言語Python
静的型付け言語Python静的型付け言語Python
静的型付け言語Pythonkiki utagawa
 
Python勉強会4-制御構文とパッケージ
Python勉強会4-制御構文とパッケージPython勉強会4-制御構文とパッケージ
Python勉強会4-制御構文とパッケージ理 小林
 
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)Hiro H.
 
普通のプログラミング言語R
普通のプログラミング言語R普通のプログラミング言語R
普通のプログラミング言語RShuyo Nakatani
 
JavaScript経験者のためのGo言語入門
JavaScript経験者のためのGo言語入門JavaScript経験者のためのGo言語入門
JavaScript経験者のためのGo言語入門Shohei Arai
 
アルゴリズムとデータ構造2
アルゴリズムとデータ構造2アルゴリズムとデータ構造2
アルゴリズムとデータ構造2Kenta Hattori
 
03 var array_flow_func
03 var array_flow_func03 var array_flow_func
03 var array_flow_func文樹 高橋
 
STLの型の使い分け(ダイジェスト版) @ Sapporo.cpp 第7回勉強会 (2014.10.18)
STLの型の使い分け(ダイジェスト版) @ Sapporo.cpp 第7回勉強会 (2014.10.18)STLの型の使い分け(ダイジェスト版) @ Sapporo.cpp 第7回勉強会 (2014.10.18)
STLの型の使い分け(ダイジェスト版) @ Sapporo.cpp 第7回勉強会 (2014.10.18)Hiro H.
 
Computation Expressions for Haxe
Computation Expressions for HaxeComputation Expressions for Haxe
Computation Expressions for Haxeterurou
 
Pythonと型チェッカー
Pythonと型チェッカーPythonと型チェッカー
Pythonと型チェッカーTetsuya Morimoto
 
関数型都市忘年会『はじめての函数型プログラミング』
関数型都市忘年会『はじめての函数型プログラミング』関数型都市忘年会『はじめての函数型プログラミング』
関数型都市忘年会『はじめての函数型プログラミング』Kenta USAMI
 
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第6回 ‟文字列とオブジェクト„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第6回 ‟文字列とオブジェクト„【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第6回 ‟文字列とオブジェクト„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第6回 ‟文字列とオブジェクト„和弘 井之上
 
リテラルと型の話 #__swift__
リテラルと型の話 #__swift__リテラルと型の話 #__swift__
リテラルと型の話 #__swift__Tomohiro Kumagai
 
Unity2015_No10_~UGUI&Audio~
Unity2015_No10_~UGUI&Audio~Unity2015_No10_~UGUI&Audio~
Unity2015_No10_~UGUI&Audio~CHY72
 
JavaScript超入門 基礎
JavaScript超入門 基礎JavaScript超入門 基礎
JavaScript超入門 基礎tetsu6
 

Mais procurados (20)

これからの「言語」の話をしよう ―― 未来を生きるためのツール
これからの「言語」の話をしよう ―― 未来を生きるためのツールこれからの「言語」の話をしよう ―― 未来を生きるためのツール
これからの「言語」の話をしよう ―― 未来を生きるためのツール
 
.NET系開発者から見たJava
.NET系開発者から見たJava.NET系開発者から見たJava
.NET系開発者から見たJava
 
Swift の3大プロトコルを眺めてみる #love_swift
Swift の3大プロトコルを眺めてみる #love_swiftSwift の3大プロトコルを眺めてみる #love_swift
Swift の3大プロトコルを眺めてみる #love_swift
 
Python と型ヒント (Type Hints)
Python と型ヒント (Type Hints)Python と型ヒント (Type Hints)
Python と型ヒント (Type Hints)
 
静的型付け言語Python
静的型付け言語Python静的型付け言語Python
静的型付け言語Python
 
Python勉強会4-制御構文とパッケージ
Python勉強会4-制御構文とパッケージPython勉強会4-制御構文とパッケージ
Python勉強会4-制御構文とパッケージ
 
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
 
普通のプログラミング言語R
普通のプログラミング言語R普通のプログラミング言語R
普通のプログラミング言語R
 
JavaScript経験者のためのGo言語入門
JavaScript経験者のためのGo言語入門JavaScript経験者のためのGo言語入門
JavaScript経験者のためのGo言語入門
 
アルゴリズムとデータ構造2
アルゴリズムとデータ構造2アルゴリズムとデータ構造2
アルゴリズムとデータ構造2
 
Perl io layer
Perl io layerPerl io layer
Perl io layer
 
03 var array_flow_func
03 var array_flow_func03 var array_flow_func
03 var array_flow_func
 
STLの型の使い分け(ダイジェスト版) @ Sapporo.cpp 第7回勉強会 (2014.10.18)
STLの型の使い分け(ダイジェスト版) @ Sapporo.cpp 第7回勉強会 (2014.10.18)STLの型の使い分け(ダイジェスト版) @ Sapporo.cpp 第7回勉強会 (2014.10.18)
STLの型の使い分け(ダイジェスト版) @ Sapporo.cpp 第7回勉強会 (2014.10.18)
 
Computation Expressions for Haxe
Computation Expressions for HaxeComputation Expressions for Haxe
Computation Expressions for Haxe
 
Pythonと型チェッカー
Pythonと型チェッカーPythonと型チェッカー
Pythonと型チェッカー
 
関数型都市忘年会『はじめての函数型プログラミング』
関数型都市忘年会『はじめての函数型プログラミング』関数型都市忘年会『はじめての函数型プログラミング』
関数型都市忘年会『はじめての函数型プログラミング』
 
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第6回 ‟文字列とオブジェクト„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第6回 ‟文字列とオブジェクト„【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第6回 ‟文字列とオブジェクト„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第6回 ‟文字列とオブジェクト„
 
リテラルと型の話 #__swift__
リテラルと型の話 #__swift__リテラルと型の話 #__swift__
リテラルと型の話 #__swift__
 
Unity2015_No10_~UGUI&Audio~
Unity2015_No10_~UGUI&Audio~Unity2015_No10_~UGUI&Audio~
Unity2015_No10_~UGUI&Audio~
 
JavaScript超入門 基礎
JavaScript超入門 基礎JavaScript超入門 基礎
JavaScript超入門 基礎
 

Semelhante a 関数型志向Python - LLまつり2013

From Java To Clojure
From Java To ClojureFrom Java To Clojure
From Java To ClojureKent Ohashi
 
Cookpad Summer Intern 2015 - Programming Paradigm
Cookpad Summer Intern 2015 - Programming ParadigmCookpad Summer Intern 2015 - Programming Paradigm
Cookpad Summer Intern 2015 - Programming ParadigmMinero Aoki
 
Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2Ransui Iso
 
F#のコンピュテーション式
F#のコンピュテーション式F#のコンピュテーション式
F#のコンピュテーション式pocketberserker
 
PHP基礎勉強会
PHP基礎勉強会PHP基礎勉強会
PHP基礎勉強会Yuji Otani
 
Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1Ransui Iso
 
Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6Ransui Iso
 
Essential Scala 第5章 シーケンス処理
Essential Scala 第5章 シーケンス処理Essential Scala 第5章 シーケンス処理
Essential Scala 第5章 シーケンス処理Takuya Tsuchida
 
第1回勉強会スライド
第1回勉強会スライド第1回勉強会スライド
第1回勉強会スライドkoturn 0;
 
Lispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
Lispmeetup #53 PythonベースのLisp方言、 HyのすすめLispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
Lispmeetup #53 PythonベースのLisp方言、 HyのすすめSatoshi imai
 
Start!! Ruby
Start!! RubyStart!! Ruby
Start!! Rubymitim
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)啓 小笠原
 
例外のlogを快適に
例外のlogを快適に例外のlogを快適に
例外のlogを快適にTakashi Kawachi
 
Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]Ra Zon
 
JavaScriptユーティリティライブラリの紹介
JavaScriptユーティリティライブラリの紹介JavaScriptユーティリティライブラリの紹介
JavaScriptユーティリティライブラリの紹介Yusuke Hirao
 
Ruby on Rails 入門
Ruby on Rails 入門Ruby on Rails 入門
Ruby on Rails 入門Yasuko Ohba
 

Semelhante a 関数型志向Python - LLまつり2013 (20)

From Java To Clojure
From Java To ClojureFrom Java To Clojure
From Java To Clojure
 
Cookpad Summer Intern 2015 - Programming Paradigm
Cookpad Summer Intern 2015 - Programming ParadigmCookpad Summer Intern 2015 - Programming Paradigm
Cookpad Summer Intern 2015 - Programming Paradigm
 
Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2
 
F#のコンピュテーション式
F#のコンピュテーション式F#のコンピュテーション式
F#のコンピュテーション式
 
PHP基礎勉強会
PHP基礎勉強会PHP基礎勉強会
PHP基礎勉強会
 
Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1
 
Python02
Python02Python02
Python02
 
Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6
 
Essential Scala 第5章 シーケンス処理
Essential Scala 第5章 シーケンス処理Essential Scala 第5章 シーケンス処理
Essential Scala 第5章 シーケンス処理
 
第1回勉強会スライド
第1回勉強会スライド第1回勉強会スライド
第1回勉強会スライド
 
Lispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
Lispmeetup #53 PythonベースのLisp方言、 HyのすすめLispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
Lispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
 
Start!! Ruby
Start!! RubyStart!! Ruby
Start!! Ruby
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)
 
例外のlogを快適に
例外のlogを快適に例外のlogを快適に
例外のlogを快適に
 
Introduction of Python
Introduction of PythonIntroduction of Python
Introduction of Python
 
Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]
 
JavaScriptユーティリティライブラリの紹介
JavaScriptユーティリティライブラリの紹介JavaScriptユーティリティライブラリの紹介
JavaScriptユーティリティライブラリの紹介
 
JavaScript入門
JavaScript入門JavaScript入門
JavaScript入門
 
たのしい関数型
たのしい関数型たのしい関数型
たのしい関数型
 
Ruby on Rails 入門
Ruby on Rails 入門Ruby on Rails 入門
Ruby on Rails 入門
 

関数型志向Python - LLまつり2013