Yesod勉強会

14,337 views

Published on

Yesod勉強会 http://partake.in/events/5f27d86f-0211-4af4-9a9e-5f123056e44e での発表資料です。

Published in: Technology, Education
0 Comments
28 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
14,337
On SlideShare
0
From Embeds
0
Number of Embeds
109
Actions
Shares
0
Downloads
80
Comments
0
Likes
28
Embeds 0
No embeds

No notes for slide

Yesod勉強会

  1. 1. HaskellとWeb開発<br />田中英行 (@tanakh)<br />tanaka.hideyuki@gmail.com<br />
  2. 2. 本日の概要<br />HaskellとWebアプリ<br />HaskellのWebフレームワーク今昔<br />ナウいHaskellのWebフレームワーク紹介<br />Yesod入門<br />
  3. 3. HaskellとWebアプリ<br />
  4. 4. なぜ、HaskellでWebアプリを書くのか?<br />速さ<br />statically typed<br />安全性<br />type-safe, XSS/SQL injection<br />記述力<br />言わずもがな<br />雇用対策(他人に保守できない)<br />
  5. 5. なぜ、HaskellでWebアプリを書くのか?<br />
  6. 6. なぜ、HaskellでWebアプリを書くのか?<br />
  7. 7. なぜ、HaskellでWebアプリを書くのか?<br />
  8. 8. なぜ、HaskellでWebアプリを書くのか?<br />
  9. 9. 現在の世の中の情勢<br />LAMP!<br />RoR!<br />Django!<br />Node.js!<br />これは潰したい<br />
  10. 10. スクリプト言語の場合<br />お手軽<br />PHPとか<br />書き換えると直ぐに反映<br />優れたフレームワークの存在<br />Ruby on Rails<br />symfony<br />Django<br />
  11. 11. なぜコンパイル言語でWebアプリは流行らないか?<br />毎度コンパイルするのが面倒<br />Webフレームワークの不在<br />Javaはそこそこ使われていたりする<br />ScalaのLiftとか?<br />ネイティブなのはあまり聞かない<br />
  12. 12. Haskellでは…?<br />Haskellインタプリタライブラリを用いた開発サーバの登場<br />コンパイル不要<br />書き換え即反映<br />新世代Webフレームワークの台頭<br />2010年あたりから<br />高速文字列ライブラリ、UTFサポートの充実、Iterateeなど優れたI/Oライブラリの整備が後押しか?<br />
  13. 13. これなら書ける!<br />
  14. 14. HaskellでのWeb開発今昔<br />
  15. 15. 昔々…<br />Web開発はCGIが主流<br />(環境変数)標準入力からの入力と、標準出力への出力が出来ればOK<br />おおよそどんなプログラミング言語でも可能<br />Web黎明期にはPerlがよく使われていた<br />
  16. 16. CGI<br />Haskellでは、かなり昔からCGIを書くためのライブラリが「標準に」入っていた<br />現在はHaskell Platform<br />モナディックライブラリ<br />CGIモナドとしてプログラムを書くと、CGIとしてだけでなく、FCGI、SCGI、はたまたスタンドアロンサーバとしても動作可能<br />
  17. 17. HTMLライブラリ<br />Text.HTML<br />これもかなり初期から標準搭載<br />
  18. 18. 例<br />import Network.CGI<br />import Text.Html<br />main :: IO ()<br />main = runCGI (handleErrorscgiMain)<br />cgiMain :: CGI CGIResult<br />cgiMain = output $ renderHtml $ do<br />thehtml <<<br /> [ header $ thetitle << "Test Page!"<br /> , body <<<br /> [ h1 << "Hoge-"<br /> , paragraph <<<br /> [ primHtml "Hello, World!" ]]]<br />
  19. 19. 参考:pficommonのCGIライブラリ<br />HaskellのCGI+HTMLを下敷きに作った<br />class my_cgi : public xhtml_cgi{<br />public:<br /> void run(){<br /> html__{<br /> head__{<br /> title__{<br /> text__("Test"); }}<br /> body__{<br /> h1__ text__("Hoge-");<br /> p__{<br /> text__("Hello, World!"); }}}}<br />};<br />int main(){<br />run_cgi(my_cgi()).run();<br />}<br />
  20. 20. Functional Online Judge<br />http://d.hatena.ne.jp/tanakh/20050919#p1<br />拙作謎のオンラインジャッジ<br />CGI+HTML+HaskellDB+Sqlite<br />
  21. 21. こういうのの何がいいのか?<br />コンパイルが通れば、ill-formedなHTMLが生成されない<br />コンパイルが通れば、XSSされない<br />
  22. 22. 何が問題なのか?<br />必要なものが揃っていない<br />Session<br />永続データ<br />パスルーティング<br />などなど<br />DBにアクセスするものはあったけど<br />IOモナドを介する貧弱なインターフェース<br />
  23. 23. 参考:HaskellDB<br />SQLを生で書くのはいけない<br />EDSL<br />ill-formedなSQLの生成を防止<br />型安全性<br />SQLインジェクション防止<br />
  24. 24. 参考:GHCの日本語対応<br />HaskellのChar型は元々32bit<br />HaskellのString = Charのリスト<br />Unicodeが普通に扱えるはずだが…<br />GHC 6.x から<br />utf8文字列受付->utf8-string->IOレイヤでの自動エンコード・デコード<br />
  25. 25. WASH<br />http://www.informatik.uni-freiburg.de/~thiemann/WASH/<br />Haskellの第一世代型Webフレームワーク<br />状態を持てる(継続ベースっぽい)<br />XMLを中に書ける(HSP)<br />
  26. 26. HSP(Haskell Server Pages)<br />EmbededなXMLコード<br />page :: (?a :: Application, ?s :: Session) => Element<br />page =<br /> <HTML><br /> <TITLE>Counter</TITLE><br /> <BODY><br /> <P><br /> This page has been accessed<br /> <%<br /> do{ n <- countPage<br /> ; return [ <IMG SRC=(i:".gif") /> | i <- show n ]<br /> }<br /> %><br /> times.<br /> </P><br /> <P><br /> You have visited this page <% countSession %> times.<br /> </P><br /> </BODY><br /> </HTML><br />
  27. 27. Happs<br />同世代のフルスタックWebフレームワーク<br />DBを使わない独自の永続データ<br />独自のマイグレーション<br />
  28. 28. そして月日は流れて…<br />第二世代型のフレームワークに<br />
  29. 29. Haskellを取り巻く環境の変遷とHaskellのナウいWebフレームワーク<br />
  30. 30. 最近のHaskell<br />2009~2010年頃、突如としてHaskellのWebフレームワークが同時多発的に登場<br />特に有望そうな物<br />Happstack<br />Happsの改良<br />Snap<br />ハイパフォーマンスを謳う<br />Yesod<br />フルスタック<br />
  31. 31. 何が起こったか?<br />Hackage(http://hackage.haskell.org/)の登場(2006~)<br />HaskellのCPANのようなもの<br />Hackageへの優れたライブラリの蓄積(2008~)<br />既存のライブラリを置き換えるようなものの登場<br />ByteString/Text<br />Unicodeの扱い<br />Iteratee<br />Haskellコミュニティーの成長<br />
  32. 32. Haskellの文字列処理の変遷<br />String (=[Char])<br />とても自明で、InductiveでRecursiveな定義<br />Haskell標準に豊富にあるリスト操作関数がそのまま使える<br />2008年頃まで、Haskellコミュニティーは何も疑問に思うことなく過ごしていた…<br />
  33. 33. Stringの欠点<br />メモリを大量に食う(4*ptr+32bit/char)<br />遅い(一文字ごとにderef2回)<br />‘H’<br />‘E’<br />‘L’<br />
  34. 34. ByteStringの登場<br />単なるByte Arrayをメモリ表現として持つByteStringの登場<br />爆速<br />適当に書いたコードだとC++より速い<br />Fusion<br />map f (map g str) をmap (f.g) strに変換するなど<br />かなりアグレッシブ<br />
  35. 35. Textの登場<br />ByteStringはエンコーディングを考慮しないバイト列だった<br />HaskellのCharはUTF32<br />そのままByteStringにできない<br />UTF16でエンコードされた16ビット列を表すTextの登場<br />先日リリースされたHaskell Platform 2011.2.0.0から標準に<br />
  36. 36. Iteratee<br />次世代I/O<br />次のすべてを満たす夢のような手法<br />高速<br />composable<br />安全<br />リソースの速やかな開放<br />
  37. 37. Iterateeの適当な説明<br />Enumerator<br />Enumeratee<br />Iteratee<br />入力データを生成<br />入力データを変換<br />入力データを消費<br />
  38. 38. そんなこんなで<br />新しいWebフレームワークの登場する土壌が整いまして…<br />
  39. 39. Happs/Happstack<br />http://happstack.com/<br />結構昔からあるフレームワーク<br />最近Happstackという名前に<br />高速化<br />Iteratee化など<br />利用例<br />happstack.com<br />gitit (http://wiki.tanakh.jp/)<br />patch-tag (http://patch-tag.com/)<br />
  40. 40. Happstack<br />フルスタックなWebフレームワーク<br />サーバー (happstack-server)<br />永続データ (happstack-state)<br />テンプレーティング<br />
  41. 41. Snap<br />http://snapframework.com/<br />2010年開発開始<br />libevを用いた高速な実装<br />Googleの人が開発?(CopyrightにGoogle Inc)<br />利用例<br />snapframework.com<br />darcsden (http://darcsden.com/)<br />barley (http://barley.tanakh.jp/)<br />
  42. 42. Snapベンチマーク<br />Pongベンチマーク<br />
  43. 43. Snapの状況<br />だが、最近は開発が停滞気味<br />ひと通り完成か?<br />フレームワークと言うには機能が少ない<br />セッションない<br />永続データない<br />ファイルアップロード機能が最近付いた<br />テストのカバレッジチェック等がきっちりと行われている<br />
  44. 44. Snap周辺ライブラリ<br />Heist<br />テンプレーティングライブラリ<br />xmlで記述<br />特定のタグでHaskellコードを呼び出せる<br />スニペットと呼ばれる<br />xmlhtml<br />既存のhtmlライブラリがしょぼいので、新しく作られた<br />これは便利<br />
  45. 45. Heiste例<br /><bind tag="longname"> Einstein, Feynman, Heisenberg,<br /> and Newton Research Corporation Ltd.<sup>TM</sup></bind><p> We at <longname/> have research expertise in many<br /> areas of physics. Employment at <longname/> carries significant <br /> prestige. The rigorous hiring process developed by <br /> <longname/> is leading the industry.</p><br />
  46. 46. Yesod<br />http://docs.yesodweb.com/<br />フルスタックなWebフレームワーク<br />HaskellのQuasiQuoteを積極的に用いた(おそらく)初めてのフレームワーク<br />WAIを介して様々な方法で実行できる<br />豊富な周辺ライブラリ<br />
  47. 47. Yesodベンチマーク<br />Pongベンチマーク<br />
  48. 48. Yesodを利用したサイト<br />http://docs.yesodweb.com/<br />yackage<br />http://www.haskellers.com/<br />http://photos.snoyman.com/<br />http://www.search-once.com/homepage/<br />
  49. 49. WAI (Web Application Interface)<br />Webアプリケーションのための近代的な汎用インターフェース<br />Yesodの人による<br />type Application = Request -> Iteratee ByteString IO Response<br />type Middleware = Application -> Application<br />
  50. 50. WAI(2)<br />Yesodアプリ<br />CGI<br />FCGI<br />Snapアプリ<br />WAI<br />Standalone<br />その他アプリ<br />devel<br />webkit<br />
  51. 51. Warp<br />Yesod作者が作った、Iterateeベースの高性能WAIバックエンドHTTPサーバ<br />
  52. 52. Yesod入門<br />
  53. 53. インストール<br />ghcをインストールする<br />$ cabal update<br />$ cabal install yesod<br />
  54. 54. 最初のサンプル<br />{-# LANGUAGE TypeFamilies, QuasiQuotes, <br />MultiParamTypeClasses, TemplateHaskell #-}importYesoddataHelloWorld = HelloWorldmkYesod“HelloWorld” [parseRoutes|/ HomeR GET|]instanceYesodHelloWorldwhereapproot_ = ""getHomeR = defaultLayout[hamlet|HelloWorld!|]main = warpDebug 3000 HelloWorld<br />
  55. 55. scaffold<br />$ mkdir test<br />$ cd test<br />$ yesod<br />質問に答える<br />テンプレができる!<br />
  56. 56. ビルド<br />$ cabal configure<br />$ cabal build<br />dist/build/…/… を実行!<br />ブラウザで見る<br />
  57. 57. Hamlet/Cassius/Julius<br />HTML/CSS/JSの各種DSL<br />それぞれQuasiQuoteとして用いる<br />!!!<br /><html<br /> <head<br /> <title>#{pageTitle pc}<br /> ^{pageHead pc}<br /> <body<br /> $maybe msg <- mmsg<br /> <div #message>#{msg}<br /> ^{pageBody pc}<br />
  58. 58. Hamlet/Cassius/Julius<br />hamlet/default-lauout.hamlet<br />テンプレ<br />hamlet/homepage.hamlet<br />各ページ<br />Handler/Root.hs<br />これらを読み込むコード<br />これらのファイルは、“コンパイル時”に読まれ、パーズされ、型検査され、well-formedなHTML等しか生成されないことが保証される<br />
  59. 59. Web Route Quasi<br /><Foundation>.hs<br />QuasiQuoteでパスを作成<br />mkYesodData"Test" [$parseRoutes|<br />/static StaticR Static getStatic<br />/authAuthRAuthgetAuth<br />/favicon.ico FaviconR GET<br />/robots.txt RobotsRGET<br />/ RootR GET<br />/user/#String/configConfigR GET POST<br />/user/#String/post/#IntPostR POST<br />|]<br />
  60. 60. Type Safe URL<br />ルートに対して、それぞれデータ型が生成される<br />Hamletへのリンク挿入時、それを利用出来る<br />404 error free!<br /><ul<br /> <li<br /> <a href=@{PortR “Hoge” 123}>ポスト<br /> <a href=@{ConfigR “Hoge”}>設定<br />
  61. 61. persistent<br />永続データを扱うライブラリ<br />Non Relational<br />割り切った設計<br />Sqlite, PostgresSQL, MongoDBなど、バックエンドのシームレスな切り替え<br />QuasiQuoteによるレコード定義<br />自動マイグレーション<br />
  62. 62. persistent例<br />share2 mkPersist (mkMigrate "migrateAll") [persist|<br />User<br />ident String<br /> name String Update<br /> password String Maybe Update<br />longName String Update default=""<br />desc Text Update default=""<br />UniqueUserident<br />UniqueUserName name<br />Post<br /> user UserIdEq In<br /> content Text<br />replyToPostId Maybe<br />replyToUserUserId Maybe<br /> date UTCTimeDesc<br />|]<br />
  63. 63. devel-server<br />wai-handler-develを使うと、ghc-apiを利用してコードをコンパイルせずに実行出来る<br />コードの変更を監視して、自動リロードされる<br />hamletの変更も監視<br />スクリプト言語のような書き心地!<br />本番運用はコンパイルして高速に実行<br />
  64. 64. webkit-handler<br />WebアプリをスタンドアロンGUIアプリのように実行出来る<br />
  65. 65. i18n<br />Yesod 0.8.1から追加<br />http://www.yesodweb.com/blog/non-poly-hamlet-i18n<br />
  66. 66. デモ<br />ご期待ください!<br />

×