...

関数プログラミングの希望 Haskellの夢

by user

on
Category: Documents
28

views

Report

Comments

Transcript

関数プログラミングの希望 Haskellの夢
関数プログラミングの希望
Haskellの夢
2012.4.17
山本和彦
1
自己紹介
山本和彦
二児の父
Haskell 歴は4年と少し
Mew、Firemacs、Mighttpd の開発者
2
おしな書き
3
関数プログラミングとは何か
4
僕の定義
5
関数型言語の仲間たち
6
静的型付き関数型言語の特徴
7
部品プログラミング
8
パラダイムの違い
9
例題
入力として整数のリストあるいは配列
10, 20, 30, 40, 50 がある
0 から数えて n 番目の要素には n を掛ける
それらをすべて足し合わせる
つまり、以下のような計算をする
10 * 0 + 20 * 1 + 30 * 2 + 40 * 3 + 50 *4 = 400
10
Ruby で逐次&反復
inject は使わない場合
def func (ar)
sum = 0;
i = 0;
ar.each{|x|
sum += x * i;
i += 1;
}
sum;
end
← 命令の列挙
← 命令の列挙
← 破壊的代入
← 破壊的代入
実行
func([10,20,30,40,50]);
→ 400
11
Haskell で map & reduce
zip [0..] [10,20,30,40,50]
→ [(0,10),(1,20),(2,30),(3,40),(4,50)]
map (\(i,x) -> x*i) (上記の式)
→ [0,20,60,120,200]
foldl (+) 0 (上記の式)
→ ((((0 + 0) + 20) + 60) + 120) + 200
→ 400
関数を合成する
func = foldl (+) 0
. map (\(i,x) -> x*i)
. zip [0..]
func [10,20,30,40,50]
→ 400
12
部品プログラミング
信号処理回路のようなプログラミング
13
合成可能 (再利用可能)
関数型言語では関数が合成し易い
関数が本当に独立した部品だから
クラスベースのオブジェクト指向では合成が困難
オブジェクトが環境を引きずるから
14
高いエラー検出率
15
型の神話
16
役に立つ静的型付き言語
17
関数型言語とは
「すべては式」
を活かしている言語
18
Ruby でフィボナッチ数
すべては式だけれど命令的に書ける
19
Haskell でフィボナッチ数
すべては式である
20
コンパイルはテスト
あらゆる場所で式と式の型の関係が検査される
21
静的型付き関数型言語では
自然とテスト駆動となる
コンパイルを通れば
型に関する間違いはない
値に関するテストは必要
22
値に関するテスト
23
おススメの書籍
Scheme 手習い
再帰を学ぶ
プログラミングの基礎
関数プログラミングを学ぶ
OCaml、浅井健一著
プログラミングHaskell
関数プログラミングを学ぶ
Scalaスケーラブルプログラミング第2版
Java プログラマーにお勧め
24
Haskell の実用的な話題
25
Yesod とは何か?
Haskell で書かれたフルスタックの
Web アプリケーション・フレームワーク
26
Haskell
コンパイルが通れば
だいたい思い通りにプログラムが動く
Yesod
コンパイルが通れば
だいたい思い通りに Web アプリが動く
27
Hello, world!
28
Yesod を支える技術
29
安全対策技術
30
ルーティング情報
型安全
mkYesod "HelloWorld" [parseRoutes|
/
HomeR GET
/hello HelloR GET
|]
型の自動生成
data Route = HomeR | HelloR
実際にはもっと複雑ですが...
型で守るURL
@{} は Route 型を要求する
getHomeR :: Handler RepHtml
getHomeR = defaultLayout [whamlet|
<a href=@{HelloR}>Go to hello page!
|]
アプリ内ではリンク切れなし!
31
Template Haskell
関数型言語ではパーサの作成が簡単
パーサコンビネータのおかげ
気軽に DSL を作れる
準クオート
"[parser|" と "|]" の間に DSL を書く
mkYesod "HelloWorld" [parseRoutes|
/
HomeR GET
/hello HelloR GET
|]
展開
コンパイル時に構文木を生成する
data Route = HomeR | HelloR
...
型検査の対象となる
32
No No No
33
似て非なるものの区別
Echo アプリ
mkYesod "HelloWorld" [parseRoutes|
/echo/#Text EchoR GET
|]
getEchoR :: Text -> Handler RepHtml
getEchoR = defaultLayout . toWidget . echoHtml
echoHtml :: Text -> a -> Html
echoHtml txt = [hamlet|<h1>#{txt}|]
URL
%3Cscript%3Ealert%28%22Danger
%21%22%29%3B%3C%2Fscript%3E
Text
<script>alert("Danger!");</script>
Html
&lt;script&gt;alert(&quot;Danger!&quot;);
&lt;/script&gt;
34
各種DSL
Hamlet (HTML, Html 型)
<h1 .page-title>#{pageTitle}
<p>This is the home page of...
Cassius (CSS, Css 型)
#myid
color: #{red}
font-size: #{bodyFontSize}
Julius (JavaScript, Javascript 型)
$(function(){
$("section.#{sectionClass}").hide();
$("#mybutton").click(function(){
document.location = "@{SomeRouteR}";
});
^{addBling}
});
型を考慮して変数を埋め込める(interpolate)
35
Widget
36
高速化技術
37
Yesod / Warp の速度
Ping pong ベンチマーク
38
高速文字列処理
BlazeBuiler
差分リストのアイディアに基づいた
高速に文字列を連結するライブラリ
文字列連結
Haskell の文字列は変更できないので、安全に共有できる
関数合成は O(1)
出力
出力の際に、はじめて出力バッファにコピーされる
39
Conduit とは何か?
Unix のパイプに似ている
第二世代の Iteratee
40
合成可能とは何か?
悪しき一枚岩による実装
replicate :: Int -> a -> [a]
replicate 0 _ = []
replicate n x = x : replicate (n - 1) x
合成による実装
replicate n x = take n $ repeat x
Conduit でのファイルのコピー
copyFile :: FilePath -> FilePath -> IO ()
copyFile src dst = runResourceT $
CB.sourceFile src $$ CB.sinkFile dst
41
Conduit での合成
42
Warp と Conduit
43
高速サーバ
高速化にはイベント駆動が必須
プロセス・プール、ネイティブ・スレッド・プールでは遅い
多くの言語ではコールバック (イベント・ハンドラ)
Haskell では軽量スレッド
44
軽量スレッド
ユーザ空間で実装されたスレッド
ネイティブ・スレッドとは異なる
軽量
10万個作成しても大丈夫
軽量スレッドの切り替え時には、
カーネルへのコンテキスト・スイッチが発生しない
Haskell に特有の機能
ライブラリはノンブロッキングとなるよう実装されている
外部言語呼び出しでブロックしても大丈夫
外部言語呼び出しにはネイティブ・スレッドを使う
非同期例外
ある軽量スレッドが、他の軽量スレッドを kill できる
ほとんどの計算が純粋なので、突然例外を受け取ってもよい
45
Warp が発行するシステムコール
軽量スレッドの敵はシステムコール
カーネルにコンテキストスイッチして、
すべての軽量スレッドが止まる
なるべくシステムコールは発行しない
stat() で得た情報などはキャッシュすべき
46
Yesod のサイト
参考文献
http://www.yesodweb.com/
Yesod のチュートリアル
"Haskell web programming"
http://yannesposito.com/Scratch/en/blog/
Yesod-tutorial-for-newbies/
Haskell and Yesod
オライリーから近日発売
47
(STMなどの)質問は
懇親会
または
@kazu_yamamoto
48
Fly UP