SlideShare a Scribd company logo

      
       Caty Framework 
      
     
      
       〜Back to Oldies, Back to Basics〜 
      
     
      
       言い出しっぺ: 檜山正幸 
       巻き込まれた人:鍬田力

      
       Catyを作り始めた経緯 
      
     
      
       檜山さんにお任せします。

      
       ちょっくらWebサイトでも 
      
     
      
       
        * 
        少しだけ動的 
       
       
        * 
        デザインはプロに頼もう 
       
       
        * 
        どうやってデザイナに頼んだらいいんだ? 
       
       
        * 
        周りの人に聞いてみた 
       
       
        * 
        … …

      
       ええええーーっ 
      
     
      
       
        * 
        当方、「小規模、少人数、少ない予算、短期間」なんですけど 
       
       
        * 
        本格的なフレームワークや方法論はどれもオーバースペック 
       
       
        * 
        全部ひとりでやるってのは確かにあるけど 
       
       
        * 
        「N = 1」 と 「N = それなり」の道具と手段はあるんだな 
       
       
        * 
        でも、「N = 2」「N = 3」あたりで適切なんが見あたらない

      
       んじゃ、作ろうか 
      
     
      
       
        * 
        当初の目的に適合することが第一 
       
       
        * 
        他の要求は知らん 
       
       
        * 
        だったら、簡単そうじゃん 
       
       
        * 
        … … 
       
       
        * 
        … … 
       
       
        * 
        それでエライことになった人が一人いたりします

      
       厳密分離の原理 
      
     
      
       
        * 
        これだ! 
       
       
        * 
        だけど、イマイチなところもあるなー 
       
       
        * 
        分離の境界線を1本から3本にしてみました

      
       昨日あたりから、いきなり重要キーワード 
      
     
      
       
        * 
        ロール 
       
       
        * 
        スーパーバイザー

      
       デザイナって言葉が曖昧すぎたわけだが 
      
     
      
       
        * 
        小規模、少ない予算なら、プロジェクトチームっても、2人くらいでしょう 
       
       
        * 
        狭義のデザイナ、狭義のプログラマのどちらかがスーパーバイザを兼任できそう 
       
       
        * 
        僕(檜山)はやりたくないので、デザイナさん、そっちもお願い 
       
       
        * 
        単機能のプログラム(コマンド)なら書いてもいいし、アルバイト君にも依頼可能

      
       それはそうとして

      
       Catyの問題点

      
       1. できてない 
      
     
      
       
        * 
        動くっちゃ動く 
       
       
        * 
        来週くらいにリリース2 
       
       
        * 
        やることが色々増えちゃってねー 
       
       
        * 
        … … 
       
       
        * 
        … … 
       
       
        * 
        それでエライことになってる人が一人いたりします

      
       2. ロゴがない

      
       これなんかどうか

      
       これは?

      
       これとか?

      
       募集中

      
       檜山さんの野望 
       厳密分離の実現のために 
      
     
      
       
        * 
        プログラマに頼らずサイト全体を構築可能 
       
       
        * 
        三つのロールモデル間の分業 
       
       
        o 
        デザイナー 
       
       
        o 
        プログラマー 
       
       
        o 
        スーパーバイザー 
       
       
        * 
        特にプログラマーとの間で分業 
       
       
       ※スーパーバイザーはサイト全体の構造・仕様についての責務を負う人とする

      
       昔は良かった 
      
     
      
       
        * 
        Webサイト=HTMLだけで構成 
       
       
        * 
        CGIもあったけど、何にせよファイルはモロ見え 
       
       
        * 
        ファイラーでサイトの構造が見える 
       
      
     
      
       ~/public_html/index.html 
       ~/public_html/news/9901.html 
       ~/cgi-bin/forum.cgi 
       : 
       : 
      
     
      
       http://example.com/ 
       http://example.com/news/... 
       http://example.com/forum.cgi 
       : 
       :

      
       今は便利になったけど(1) 
      
     
      
       
        * 
        URLマッピングとフィルター・トリガーの嵐 
       
       
        * 
        FWを知らないとサイトの構造が不明 
       
       
        * 
        そして当然それらはFW依存 
       
      
     
      
       /app/conf.xml 
         /handlers/ 
         /filters/ 
         /otherbullshits/ 
       ----------------------------------- 
       <web> 
        <action path=&quot;/*.act&quot; 
         class=&quot;Dispatcher&quot;/> 
       </web> 
      
     
      
       http://example.com/ 
       http://example.com/news.act 
       http://example.com/forum.act 
       : 
       : 
      
     
      
       ?

      
       今は便利になったけど(2) 
      
     
      
       
        * 
        いくら何でもパワフル過ぎるテンプレート 
       
       
        * 
        ちょっとした事を試すにもプログラマ頼み 
       
       
        * 
        そのくせデフォルトでXSSに脆弱だったり 
       
      
     
      
       <html> 
       <title><%= page.getTitle()%><title> 
       <ul> 
       <% for item in page.listItems() %> 
       <li><%= item.someMethod() %></li> 
       <% end %> 
       </ul> 
       </html>

      
       でもそこまでする必要ある? 
      
     
      
       
        * 
        近所のラーメン屋のサイト作るとき 
       
       
        * 
        美容院のサイト作るとき 
       
       
        * 
        そこらの片手間企業サイトを作るとき 
       
      
     
      
       オーバースペック

      
       そのやり方でいいの? 
      
     
      
       
        * 
        HTMLだけ書いてもらいそこにテンプレートのプレースホルダー埋め込み 
       
       
        * 
        デザイナーの書いたテンプレートに後から ロジック埋め込み 
       
       
        * 
        その辺ゴチャゴチャで脆弱性上等の某ソフト 
       
      
     
      
       まともに分業できてないでしょ

      
       基本を忘れてない? 
      
     
      
       
        1 
        ページのデザインに責任を負っているのは誰? 
       
       
        2 
        動的サイトに必要なプログラムを作るのは誰? 
       
       
        3 
        それらサイトの構成を把握するべきなのは誰?

      
       3つのロール 
      
     
      
       
        * 
        デザイナー 
       
       
        * 
        プログラマー 
       
       
        * 
        スーパーバイザー 
       
      
     
      
       Caty の想定するロール

      
       ロール間の分業 
      
     
      
       
        * 
        3つのロール間の責務を可能な限り分離 
       
       
        * 
        複数のロールを兼務することは当然ある 
       
       
        o 
        が、ある瞬間のロールは一つ 
       
       
        o 
        やってる事が混線しないような仕組み

      
       そのために何が要る? 
      
     
      
       
        * 
        ロジックがテンプレートに入り込まない仕組み 
       
       
        * 
        プログラマに頼らずに 
       
       
        o 
        テンプレートを実行する仕組み 
       
       
        o 
        データをマッシュアップする仕組み 
       
       
        o 
        サイトの構成を把握できる仕組み 
       
       
        * 
        安全性・整合性を保証する仕組み

      
       でも一番大事なのは 
      
     
      
       学習の容易さ

      
       古き良き日々よ再び 
      
     
      
       
        * 
        URLが存在する=ファイルが存在する 
       
       
        * 
        ベタHTMLのサイトが普通に作れる 
       
       
        * 
        そこに動的ページを混ぜ込める 
       
       
        * 
        ベターなHTML+CGIのモデル

      
       ということを考えていたら 
      
     
      
       
        * 
        予想の斜め上のフレームワークが 
       
       
        * 
        作ってる方は死にかけてる 
       
       
        * 
        とりあえずはテンプレートから説明します

      
       テンプレートのダメな例 
      
     
      
       
        * 
        あるショップのディスカウントセール 
       
       
        * 
        お店のサイトで一律値引き表示をさせたい 
       
       
        * 
        テンプレートで計算させちゃった♪ 
       
      
     
      
       <ul> 
       <% for item in page.itemList() %> 
       <li><%= item.name() %>: <%= item.price() * 0.7 %>円 </li> 
       <% end %> 
       </ul>

      
       なぜダメか 
      
     
      
       
        * 
        誰がそのロジックを書くのか 
       
       
        * 
        仮にデザイナーだとすると 
       
       
        o 
        ロジックを書くのは本業じゃない 
       
       
        * 
        仮にプログラマーだとすると 
       
       
        o 
        テンプレートをいじるのは本業じゃない 
       
       
        * 
        スーパーバイザー? 指示出す側だろ 
       
       
        * 
        分業にならない 
       
       
        * 
        そもそも保守不能なカオス

      
       ってかどうしてこうなった 
      
     
      
       
        * 
        そりゃあ、出来るからに決まってるだろ 
       
       
        * 
        最初からできなければ良い 
       
      
     
      
       低機能なテンプレートエンジンが理想

      
       Catyのテンプレートの機能 
      
     
      
       <html> 
       <title>{$title|toupper}</title> 
       {if message.exists} 
       <p>{$message.body}</p> 
       {/if} 
       <ul> 
       {foreach from=$list item=i} 
       <li>{$i}</li> 
       {/foreach} 
       </ul> 
       {include file=&quot;footer.html&quot;} 
       </html>

      
       こんだけあれば十分じゃん 
      
     
      
       
        * 
        変数参照 
       
       
        * 
        ループ 
       
       
        * 
        真偽値判定 
       
       
        * 
        他のテンプレートのインクルード 
       
       
        * 
        フィルター/モディファイアの適用

      
       こんなのは要らない 
      
     
      
       
        * 
        ホスト言語の呼び出し 
       
       
        * 
        算術演算 
       
       
        * 
        マクロ定義 
       
      
     
      
       あると厳密分離にならなくなるものばかり

      
       実は言い出しっぺは別にいる 
      
     
      
       
        * 
        Terrence Parrの論文 - Enforcing strict model-view separation in template engines 
       
       
        o 
        http://www.cs.usfca.edu/~parrt/papers/mvc.templates.pdf 
       
       
        * 
        良いテンプレート=低機能なテンプレート 
       
       
        * 
        この厳密分離の方針で実績がある

      
       厳密分離の次にすべき事 
      
     
      
       
        * 
        テンプレートだけでは動作しない 
       
       
        * 
        値を入れて確認できるようにしたい 
       
       
        * 
        わざわざプログラマに頼む必要なしにしたい 
       
      
     
      
       
        * 
        ロジックは書けなくていい 
       
       
        * 
        データを流し込む仕組みは必要

      
       よし、それじゃあJSONだ 
      
     
      
       <?caty-script 
       { 
       &quot;title&quot;: &quot;index page&quot;, 
       &quot;message&quot;: { 
       &quot;exists&quot;: true, 
       &quot;body&quot;: &quot;...&quot; } 
       } 
       ?> 
       <html> 
       <title>{$title}</title> 
       :

      
       動的データを埋め込みたい 
      
     
      
       
        * 
        固定値だけ入れられてもそこまで嬉しくはない 
       
       
        * 
        やはり動的なデータの取得が必要 
       
       
        * 
        できればデータをマッシュアップしたい 
       
      
     
      
       限られた機能のスクリプトを作ろう

      
       Catyスクリプト 
      
     
      
       <?caty-script 
       { 
       &quot;title&quot;: &quot;index page&quot;, 
       &quot;message&quot;: load-message, 
       &quot;list&quot;: fetch-db | filter 
       } 
       ?> 
       <html> 
       <title>{$title}</title> 
       :

      
       一体これは何? 
      
     
      
       
        * 
        ベターJSONとしてのスクリプト 
       
       
        * 
        JSONのスカラーの書けるところにコマンドが書ける 
       
       
        * 
        コマンド呼び出しはUnixのそれ 
       
       
        * 
        コマンドの実態はホスト言語で書かれてる 
       
       
        * 
        ロジックはコマンドに書いてください 
       
       
        * 
        Catyスクリプトはコマンドを呼び出すのみ

      
       Catyスクリプトにないもの 
      
     
      
       
        * 
        関数定義 
       
       
        * 
        ループ 
       
       
        * 
        算術演算など各種演算 
       
       
        * 
        etc 
       
      
     
      
       
        * 
        あるとホスト言語との境界が曖昧に 
       
       
        * 
        つまり厳密分離にならなくなる

      
       デザイナーの立場からは 
      
     
      
       
        * 
        HTMLだけでページが作れる 
       
       
        * 
        ベターHTMLとしてのテンプレート 
       
       
        o 
        共通フッタのインクルードだけ書くとか 
       
       
        * 
        テンプレートの表示確認用にJSONを書く 
       
       
        * 
        ベターJSONとしてのCatyスクリプト 
       
      
     
      
       段階的な学習

      
       ちょっと視点を変えてみる 
      
     
      
       
        * 
        スクリプトはテンプレートにしか書けないの? 
       
       
        * 
        サイトの構成はどうなってるの? 
       
      
     
      
       これらはスーパーバイザーの立場

      
       テンプレートに値を渡す方法 
      
     
      
       
        * 
        一つはさっきのやり方(インラインスクリプト) 
       
       
        * 
        別のスクリプト:アウトオブラインスクリプト 
       
       
        * 
        CGI 
       
       
        * 
        サイトの設定ファイル

      
       アウトオブラインスクリプト 
      
     
      
       /index.html 
       /index.html.caty 
       /news.html 
       /news.html.caty 
       : 
       : 
      
     
      
       
        * 
        ファイル毎に一つのスクリプトを関連付けられる 
       
       
        * 
        拡張子込みのファイル名+.caty 
       
       
        * 
        中身はCatyスクリプト

      
       どんな時に使うの? 
      
     
      
       
        * 
        ページの構成要素は決まってる 
       
       
        * 
        デザインはデザイナーに任せる 
       
      
     
      
       
        * 
        アウトオブラインスクリプトを書く 
       
       
        * 
        対応する空のHTMLファイルを渡す 
       
       
        * 
        コマンドが必要ならプログラマに発注

      
       例えばこんなのはどう? 
      
     
      
       
        * 
        サイトのトップページを作る 
       
       
        o 
        新着記事一覧 
       
       
        o 
        雑多なお知らせ 
       
      
     
      
       必要な要素はわかってるのでスクリプトに書ける

      
       書いてみるとこんな感じ 
      
     
      
       { 
       &quot;news&quot;: fetch-news --sort-by-date, 
       &quot;message&quot;: load-message 
       } 
      
     
      
       
        * 
        残りの作業はプログラマーとデザイナーがやる 
       
       
        * 
        fetch-newsなどをプログラマーが実装 
       
       
        * 
        HTMLテンプレートをデザイナーが作成

      
       CGI 
      
     
      
       
        * 
        CatyのCGI=Catyスクリプト 
       
       
        * 
        つまりロジックは書けません 
       
       
        * 
        サイトの表面からはロジックを分離

      
       CGIの例 
      
     
      
       
        * 
        リリース2に含まれるWikiのCGI 
       
       
        * 
        どれもこれもワンライナー 
       
      
     
      
       index.cgi: 
       wikititles / | print index.html 
       edit.cgi: 
       editwiki / | print edit.html 
       post.cgi: 
       postwiki /

      
       サイトの設定ファイル 
      
     
      
       
        * 
        拡張子毎のデフォルトコマンドを設定できる 
       
       
        * 
        が、デフォルト設定でサイトが十分構築できる 
       
       
        * 
        よく使いそうなパターンはデモに収録 
       
       
        * 
        URLマッピングの類はない 
       
      
     
      
       &quot;filetypes&quot;: { 
       &quot;.wiki&quot;: { 
       &quot;is_text&quot;: true, 
       &quot;assoc&quot;: &quot;viewwiki %1 | print page.html&quot; 
       } 
       }

      
       サイトの構成は単純 
      
     
      
       
        * 
        URLがある=公開ディレクトリにファイルがある 
       
       
        o 
        インクルード専用ディレクトリなどはある 
       
       
        * 
        公開ディレクトリやテンプレート置き場を指定 
       
       
        * 
        覚えることはあまりないです 
       
      
     
      
       /mysite 
       _manifest.json <- 設定ファイル 
       /pub <-公開ディレクトリ 
       /index.html 
       /forum.cgi 
       /templates <- インクルードやprint経由でのみアクセス 
       /res   <- コマンドの使うデータ置き場

      
       一旦まとめ 
      
     
      
       
        * 
        古典的なWebサイトの延長 
       
       
        * 
        個々の要素は限られた機能を持つ 
       
       
        * 
        単純化による学習容易性 
       
       
        * 
        機能が限られていれば自然と分業できる

      
       Catyの真の姿 
      
     
      
       
        * 
        Catyのコア=言語処理系 
       
       
        * 
        厳密分離の核心がCatyスクリプトにある 
       
       
        * 
        その処理系こそがCatyの本質 
       
      
     
      
       WebフレームワークとしてのCaty 
       = 
       CatyスクリプトのWebフロントエンド

      
       Catyはこんな構成 
      
     
      
       
       Catyスクリプト処理系 
      
     
      
       シェルフロントエンド 
      
     
      
       Webフロントエンド 
      
     
      
       キーボード入力 
      
     
      
       HTTPアクセス

      
       コンソールとWebが対等 
      
     
      
       caty> print --resolve /index.html 
       = 
       GET /index.html HTTP/1.1 
       
       caty> {&quot;path&quot;:&quot;Example&quot;}|/edit.cgi 
       = 
       GET /edit.cgi?path=Example 
       
       caty> {&quot;path&quot;:&quot;Example&quot;, &quot;content&quot;: &quot;hogehoge&quot;} | /post.cgi 
       = 
       POST /post.cgi HTTP/1.1 
       path=Example&content=hogehoge

      
       Catyスクリプトの仕様書 
      
     
      
       pipeline -> term ('|' term)* 
       term -> scalar | command | object | list | 
       functor | tag | when | '(' term ')' 
       scalar -> string | integer | number | boolean 
       list ->  '[' pipeline (',' pipeline)* ']' 
       object -> '{' item (',' item)* '}' 
       item -> string ':' pipeline 
       command -> symbol option* (symbol|scalar)* 
       symbol -> ('a'..'z' | 'A'..'Z') ('a'..'z' | 'A'..'Z' | '0'..'9' | '_')* 
       tag -> '@' string | symbol 
       option -> &quot;--&quot; symbol symbol | scalar 
       functor -> symbol '{' pipeline '}' 
       when -> &quot;when&quot; '{' case (',' case)* '}' 
       case -> symbol | string &quot;=>&quot; | &quot;==>&quot; pipleline

      
       改めてCatyスクリプトを説明(1) 
      
     
      
       
        * 
        あくまでもテンプレートとホスト言語の仲立ち 
       
       
        * 
        Unixのパイプの発想 
       
       
        * 
        ネイティブデータはストリームではなくJSON 
       
       
        * 
        スーパーバイザーとデザイナーが対象に入る 
       
       
        * 
        プログラマが書いても悪くはないよ?

      
       改めてCatyスクリプトを説明(2) 
      
     
      
       
        * 
        JSON構文はそのまま使える 
       
       &quot;string&quot; 
       [1, 2, 3] 
       {&quot;name&quot;:&quot;鍬田力&quot;, &quot;job&quot;:&quot;自称料理研究家&quot;} 
       
        * 
        JSON構文にコマンドを入れ込める 
       
       print /index.html 
       [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;] | concat 
       { 
       &quot;blogTitles&quot;: blog:recentBlogEntries , 
       &quot;wikiTitles&quot;: wiki:recentUpdatedWiki 
       }

      
       改めてCatyスクリプトを説明(3) 
      
     
      
       
        * 
        タグディスパッチによる分岐 
       
       loggedin --as kuwata | when { 
       OK => print -e /secret.html, 
       NG => &quot;/login.html&quot; | redirect 
       } 
       
        * 
        Catyでは任意のデータにタグが付けられる 
       
       @person { 
       &quot;name&quot;:&quot;檜山正幸&quot;, 
       &quot;job&quot;:&quot;キマイラ飼育記の中の人&quot; 
       } 
       
        * 
        object型にpersonというメタ情報が付く 
       
       
        * 
        メタ情報が付いた型は元の型とは違う

      
       改めてCatyスクリプトを説明(4) 
      
     
      
       
        * 
        繰り返しの代わりのeach(map関数) 
       
       [&quot;foo&quot;, &quot;bar&quot;, &quot;buz&quot;] | each {toupper} 
       
       
      
     
      
       通常使うCatyスクリプトの要素はこれで全部

      
       余談:普通は使わないコマンド 
      
     
      
       
        * 
        テストの実行時のみ有効なコマンド: eval 
       
       [&quot;print /index.html&quot;, {...}] | eval 
       = 
       {...} | print /index.html 
       
        * 
        通常のコンソールやWebでは使えません 
       
       
        * 
        その理由は……

      
       こんな事が書けてしまう 
      
     
      
       test:list-testfiles / | each { { 
       &quot;testcase&quot;: pass, 
       &quot;testresult&quot;: ( 
       [&quot;readFile --readfrom testfiles &quot;, pass] | concat | [pass, &quot; &quot;] | eval | 
       [pass, &quot;&quot;] | eval | each { { 
       &quot;command&quot;: getpv command, 
       &quot;results&quot;: 
       [{&quot;command&quot;: getpv command, &quot;data&quot;: getpv data}, findpv setup, findpv teardown] | 
       [ 
       nth 1 | when {EXISTS => [pass, &quot; &quot;] | eval, NO => pass}, 
       nth 0 | 
       [getpv command, getpv data | unzip | nth 0, getpv data | unzip | nth 1] | 
       [[nth 0, nth 1 | length] | repeat, nth 1, nth 2] | 
       [[nth 0, nth 1] | zip | each {eval}, nth 2] | zip | 
       each { 
       eq | when { 
       &quot;Same&quot; => &quot;[OK]&quot;, 
       &quot;Diff&quot; => [&quot;[NG] &quot;, toString] | concat, 
       } 
       } | enumerate, 
       nth 2] | [nth 2 | when {EXISTS => [pass, &quot; &quot;] | eval, NO => pass}, nth 1] | nth 1 
       } 
       } 
       ) 
       } | expand testresult.txt 
       } | concat | chop

      
       さらなる悪夢 
      
     
      
       &quot;[pass, pass] | eval&quot; | [pass, pass] | eval 
       
        * 
        無限に再帰します 
       
       
        * 
        ってか Y コンビネータです 
       
       
        * 
        即ちチューリング完全

      
       チューリング完全性との戦い 
      
     
      
       
        * 
        あくまでもCatyスクリプトは低機能が第一義 
       
       
        * 
        あまりパワフルだと弊害が多い 
       
       
        o 
        静的検証への悪影響 
       
       
        o 
        安全性への悪影響 
       
       
        o 
        そもそも使うのも学のも難しくなる 
       
       
        * 
        ただし、evalが必要なケースがある 
       
       
        o 
        テスティングフレームワーク

      
       Catyスクリプトの型 
      
     
      
       
        * 
        パイプは確かに気軽に使える 
       
       
        * 
        でも繋げるコマンドを間違えることもある 
       
       
        * 
        可能な限り実行前に検出したい 
       
      
     
      
       JSONスキーマによる型付け

      
       JSONスキーマの基本型 
      
     
      
       
        * 
        スカラー型 
       
       string, binary, integer, number, boolean, null 
       
        * 
        配列・リスト・タプル型 
       
       array [integer, string*], list[string], tuple [string, integer] 
       
        * 
        オブジェクト型 
       
       object {&quot;name&quot;: string, &quot;job&quot;: string, &quot;age&quot;: integer} 
       
        * 
        特殊型 
       
       any, never, void 
       
        * 
        型変数 
       
       _S, _T, _U...

      
       JSONスキーマの型構築子 
      
     
      
       
        * 
        |:ユニオン型 
       
       
        o 
        string | null で「stringあるいはnull」 
       
       
        * 
        &:インターセクション型 
       
       
        o 
        A & B で「A, B両方の要素を持つ」 
       
       
        o 
        object にしか使えません 
       
       
        * 
        ?:オプショナル型 
       
       
        o 
        object {&quot;name&quot;:string, &quot;email&quot;:string?} 
       
       
        o 
        &quot;email&quot;プロパティがないかも 
       
       
        * 
        @tag:タグ 
       
       
        o 
        @person {&quot;name&quot;:string, &quot;age&quot;:integer}

      
       JSONスキーマの例 
      
     
      
       type httpResponse = object { 
       &quot;header&quot;: { 
       *: string 
       }, 
       &quot;body&quot;: string | binary, 
       &quot;status&quot;: string, };

      
       スキーマによる型付け 
      
     
      
       
        * 
        あらゆるコマンドは入出力の型を持つ 
       
       
        * 
        コマンド同士の結合時には型チェックがされる 
       
       
        o 
        今はちょっと適当 
       
       
        o 
        そのうちきちんと実装します 
       
       
        * 
        型チェックの基準 
       
       
        o 
        A | B の結合が成立する条件 
       
       
        o 
        Aの出力型がBの入力型に包含されている 
       
       
        * 
        型変数を導入したので多相コマンドが書ける 
       
       
        * 
        型変数は型推論されて型チェックされる

      
       今日は説明しませんでしたが 
      
     
      
       
        * 
        コマンドの型を指定するための機構もあります 
       
       
        * 
        そちらはDIの宣言にもなってます 
       
       
        * 
        宣言しないとファイル・DB・セッションなどへのアクセスがほぼ不可能です 
       
       
        * 
        宣言時に読み込み・書き込みの指定もします 
       
       
        * 
        つまり、型宣言をみれば副作用の有無がわかります

      
       まとめ 
      
     
      
       
        * 
        フロント部分は素朴な構造 
       
       
        o 
        学習容易性が大事 
       
       
        o 
        限られた機能で自然な分業 
       
       
        * 
        バックはガチガチに定式化 
       
       
        o 
        宣言的な仕様の記述 
       
       
        o 
        強い型システム

      
       ご清聴有難うございました

More Related Content

PDF
データ分析-の波乗り遅れた気がしてる人のための Python×データ分析の超基礎の基礎 v1.0-20160831
PDF
Janog31 bof-pattern-sasaki-01
PPTX
ASP.NETで お手軽Ajax実装
PDF
JavaScriptで出来る、あんなことこんなこと
PPTX
システム開発は何故揉めるのか
PDF
Verkko kieltenopetuksessa
PDF
Digital presence in social media
PDF
Saukon Taivaspaikka ja Creative Commons
データ分析-の波乗り遅れた気がしてる人のための Python×データ分析の超基礎の基礎 v1.0-20160831
Janog31 bof-pattern-sasaki-01
ASP.NETで お手軽Ajax実装
JavaScriptで出来る、あんなことこんなこと
システム開発は何故揉めるのか
Verkko kieltenopetuksessa
Digital presence in social media
Saukon Taivaspaikka ja Creative Commons

Viewers also liked (7)

PDF
Verkko-opettajia
PDF
Sanaston oppiminen ja opettaminen
PDF
Web strategy
PDF
Ipad opetuksessa
PDF
Kieltenopettajia verkossa
PDF
Visuaalisuus oppimisen tukena
PDF
E-Learning at JAMK 2015
Verkko-opettajia
Sanaston oppiminen ja opettaminen
Web strategy
Ipad opetuksessa
Kieltenopettajia verkossa
Visuaalisuus oppimisen tukena
E-Learning at JAMK 2015
Ad

Similar to Bpstudy26 (20)

PDF
Python3 プログラミング勉強会
PPTX
上司が信用できない会社の内部統制~第32回WebSig会議「便利さと、怖さと、心強さと〜戦う会社のための社内セキュリティ 2013年のスタンダードとは?!...
PDF
Mojoliciousでつくる! Webアプリ入門
PPTX
エンジニアが Webを学ぶために やっててよかったこと
PDF
Resemaraを支えた技術 フライングゲットガチャの舞台裏 #ksgstudy #ドリコム
PDF
MTプラグイン入門以前
PDF
Androidの新ビルドシステム
PPTX
Git & GitHub & kintone でウルトラハッピー!
PDF
システム開発を前進させるためのGradle導入法
PDF
Yapc2012ltthon
KEY
Webサイトのようには作れない!Webアプリ設計の考え方
PPT
Koi::Bana〜恋に落ちたエンジニア〜
PDF
Enterprise Redmine
PDF
初めての Raspberry pi 〜プラレールをunityの世界の中で走らせよう〜 (1)
PDF
Djangoとweb2pyをapacheに組込む
PDF
Web frontend performance tuning
PPTX
ラジコンがネットと出会ったら
PDF
Apache CloudStack コントリビューション
PDF
20120702勉強会 webアプリ作ってみた
Python3 プログラミング勉強会
上司が信用できない会社の内部統制~第32回WebSig会議「便利さと、怖さと、心強さと〜戦う会社のための社内セキュリティ 2013年のスタンダードとは?!...
Mojoliciousでつくる! Webアプリ入門
エンジニアが Webを学ぶために やっててよかったこと
Resemaraを支えた技術 フライングゲットガチャの舞台裏 #ksgstudy #ドリコム
MTプラグイン入門以前
Androidの新ビルドシステム
Git & GitHub & kintone でウルトラハッピー!
システム開発を前進させるためのGradle導入法
Yapc2012ltthon
Webサイトのようには作れない!Webアプリ設計の考え方
Koi::Bana〜恋に落ちたエンジニア〜
Enterprise Redmine
初めての Raspberry pi 〜プラレールをunityの世界の中で走らせよう〜 (1)
Djangoとweb2pyをapacheに組込む
Web frontend performance tuning
ラジコンがネットと出会ったら
Apache CloudStack コントリビューション
20120702勉強会 webアプリ作ってみた
Ad

Bpstudy26

  • 1. Caty Framework 〜Back to Oldies, Back to Basics〜 言い出しっぺ: 檜山正幸 巻き込まれた人:鍬田力
  • 2. Catyを作り始めた経緯 檜山さんにお任せします。
  • 3. ちょっくらWebサイトでも * 少しだけ動的 * デザインはプロに頼もう * どうやってデザイナに頼んだらいいんだ? * 周りの人に聞いてみた * … …
  • 4. ええええーーっ * 当方、「小規模、少人数、少ない予算、短期間」なんですけど * 本格的なフレームワークや方法論はどれもオーバースペック * 全部ひとりでやるってのは確かにあるけど * 「N = 1」 と 「N = それなり」の道具と手段はあるんだな * でも、「N = 2」「N = 3」あたりで適切なんが見あたらない
  • 5. んじゃ、作ろうか * 当初の目的に適合することが第一 * 他の要求は知らん * だったら、簡単そうじゃん * … … * … … * それでエライことになった人が一人いたりします
  • 6. 厳密分離の原理 * これだ! * だけど、イマイチなところもあるなー * 分離の境界線を1本から3本にしてみました
  • 7. 昨日あたりから、いきなり重要キーワード * ロール * スーパーバイザー
  • 8. デザイナって言葉が曖昧すぎたわけだが * 小規模、少ない予算なら、プロジェクトチームっても、2人くらいでしょう * 狭義のデザイナ、狭義のプログラマのどちらかがスーパーバイザを兼任できそう * 僕(檜山)はやりたくないので、デザイナさん、そっちもお願い * 単機能のプログラム(コマンド)なら書いてもいいし、アルバイト君にも依頼可能
  • 9. それはそうとして
  • 10. Catyの問題点
  • 11. 1. できてない * 動くっちゃ動く * 来週くらいにリリース2 * やることが色々増えちゃってねー * … … * … … * それでエライことになってる人が一人いたりします
  • 12. 2. ロゴがない
  • 13. これなんかどうか
  • 14. これは?
  • 15. これとか?
  • 16. 募集中
  • 17. 檜山さんの野望 厳密分離の実現のために * プログラマに頼らずサイト全体を構築可能 * 三つのロールモデル間の分業 o デザイナー o プログラマー o スーパーバイザー * 特にプログラマーとの間で分業 ※スーパーバイザーはサイト全体の構造・仕様についての責務を負う人とする
  • 18. 昔は良かった * Webサイト=HTMLだけで構成 * CGIもあったけど、何にせよファイルはモロ見え * ファイラーでサイトの構造が見える ~/public_html/index.html ~/public_html/news/9901.html ~/cgi-bin/forum.cgi : : http://example.com/ http://example.com/news/... http://example.com/forum.cgi : :
  • 19. 今は便利になったけど(1) * URLマッピングとフィルター・トリガーの嵐 * FWを知らないとサイトの構造が不明 * そして当然それらはFW依存 /app/conf.xml   /handlers/   /filters/   /otherbullshits/ ----------------------------------- <web>  <action path=&quot;/*.act&quot;   class=&quot;Dispatcher&quot;/> </web> http://example.com/ http://example.com/news.act http://example.com/forum.act : : ?
  • 20. 今は便利になったけど(2) * いくら何でもパワフル過ぎるテンプレート * ちょっとした事を試すにもプログラマ頼み * そのくせデフォルトでXSSに脆弱だったり <html> <title><%= page.getTitle()%><title> <ul> <% for item in page.listItems() %> <li><%= item.someMethod() %></li> <% end %> </ul> </html>
  • 21. でもそこまでする必要ある? * 近所のラーメン屋のサイト作るとき * 美容院のサイト作るとき * そこらの片手間企業サイトを作るとき オーバースペック
  • 22. そのやり方でいいの? * HTMLだけ書いてもらいそこにテンプレートのプレースホルダー埋め込み * デザイナーの書いたテンプレートに後から ロジック埋め込み * その辺ゴチャゴチャで脆弱性上等の某ソフト まともに分業できてないでしょ
  • 23. 基本を忘れてない? 1 ページのデザインに責任を負っているのは誰? 2 動的サイトに必要なプログラムを作るのは誰? 3 それらサイトの構成を把握するべきなのは誰?
  • 24. 3つのロール * デザイナー * プログラマー * スーパーバイザー Caty の想定するロール
  • 25. ロール間の分業 * 3つのロール間の責務を可能な限り分離 * 複数のロールを兼務することは当然ある o が、ある瞬間のロールは一つ o やってる事が混線しないような仕組み
  • 26. そのために何が要る? * ロジックがテンプレートに入り込まない仕組み * プログラマに頼らずに o テンプレートを実行する仕組み o データをマッシュアップする仕組み o サイトの構成を把握できる仕組み * 安全性・整合性を保証する仕組み
  • 27. でも一番大事なのは 学習の容易さ
  • 28. 古き良き日々よ再び * URLが存在する=ファイルが存在する * ベタHTMLのサイトが普通に作れる * そこに動的ページを混ぜ込める * ベターなHTML+CGIのモデル
  • 29. ということを考えていたら * 予想の斜め上のフレームワークが * 作ってる方は死にかけてる * とりあえずはテンプレートから説明します
  • 30. テンプレートのダメな例 * あるショップのディスカウントセール * お店のサイトで一律値引き表示をさせたい * テンプレートで計算させちゃった♪ <ul> <% for item in page.itemList() %> <li><%= item.name() %>: <%= item.price() * 0.7 %>円 </li> <% end %> </ul>
  • 31. なぜダメか * 誰がそのロジックを書くのか * 仮にデザイナーだとすると o ロジックを書くのは本業じゃない * 仮にプログラマーだとすると o テンプレートをいじるのは本業じゃない * スーパーバイザー? 指示出す側だろ * 分業にならない * そもそも保守不能なカオス
  • 32. ってかどうしてこうなった * そりゃあ、出来るからに決まってるだろ * 最初からできなければ良い 低機能なテンプレートエンジンが理想
  • 33. Catyのテンプレートの機能 <html> <title>{$title|toupper}</title> {if message.exists} <p>{$message.body}</p> {/if} <ul> {foreach from=$list item=i} <li>{$i}</li> {/foreach} </ul> {include file=&quot;footer.html&quot;} </html>
  • 34. こんだけあれば十分じゃん * 変数参照 * ループ * 真偽値判定 * 他のテンプレートのインクルード * フィルター/モディファイアの適用
  • 35. こんなのは要らない * ホスト言語の呼び出し * 算術演算 * マクロ定義 あると厳密分離にならなくなるものばかり
  • 36. 実は言い出しっぺは別にいる * Terrence Parrの論文 - Enforcing strict model-view separation in template engines o http://www.cs.usfca.edu/~parrt/papers/mvc.templates.pdf * 良いテンプレート=低機能なテンプレート * この厳密分離の方針で実績がある
  • 37. 厳密分離の次にすべき事 * テンプレートだけでは動作しない * 値を入れて確認できるようにしたい * わざわざプログラマに頼む必要なしにしたい * ロジックは書けなくていい * データを流し込む仕組みは必要
  • 38. よし、それじゃあJSONだ <?caty-script { &quot;title&quot;: &quot;index page&quot;, &quot;message&quot;: { &quot;exists&quot;: true, &quot;body&quot;: &quot;...&quot; } } ?> <html> <title>{$title}</title> :
  • 39. 動的データを埋め込みたい * 固定値だけ入れられてもそこまで嬉しくはない * やはり動的なデータの取得が必要 * できればデータをマッシュアップしたい 限られた機能のスクリプトを作ろう
  • 40. Catyスクリプト <?caty-script { &quot;title&quot;: &quot;index page&quot;, &quot;message&quot;: load-message, &quot;list&quot;: fetch-db | filter } ?> <html> <title>{$title}</title> :
  • 41. 一体これは何? * ベターJSONとしてのスクリプト * JSONのスカラーの書けるところにコマンドが書ける * コマンド呼び出しはUnixのそれ * コマンドの実態はホスト言語で書かれてる * ロジックはコマンドに書いてください * Catyスクリプトはコマンドを呼び出すのみ
  • 42. Catyスクリプトにないもの * 関数定義 * ループ * 算術演算など各種演算 * etc * あるとホスト言語との境界が曖昧に * つまり厳密分離にならなくなる
  • 43. デザイナーの立場からは * HTMLだけでページが作れる * ベターHTMLとしてのテンプレート o 共通フッタのインクルードだけ書くとか * テンプレートの表示確認用にJSONを書く * ベターJSONとしてのCatyスクリプト 段階的な学習
  • 44. ちょっと視点を変えてみる * スクリプトはテンプレートにしか書けないの? * サイトの構成はどうなってるの? これらはスーパーバイザーの立場
  • 45. テンプレートに値を渡す方法 * 一つはさっきのやり方(インラインスクリプト) * 別のスクリプト:アウトオブラインスクリプト * CGI * サイトの設定ファイル
  • 46. アウトオブラインスクリプト /index.html /index.html.caty /news.html /news.html.caty : : * ファイル毎に一つのスクリプトを関連付けられる * 拡張子込みのファイル名+.caty * 中身はCatyスクリプト
  • 47. どんな時に使うの? * ページの構成要素は決まってる * デザインはデザイナーに任せる * アウトオブラインスクリプトを書く * 対応する空のHTMLファイルを渡す * コマンドが必要ならプログラマに発注
  • 48. 例えばこんなのはどう? * サイトのトップページを作る o 新着記事一覧 o 雑多なお知らせ 必要な要素はわかってるのでスクリプトに書ける
  • 49. 書いてみるとこんな感じ { &quot;news&quot;: fetch-news --sort-by-date, &quot;message&quot;: load-message } * 残りの作業はプログラマーとデザイナーがやる * fetch-newsなどをプログラマーが実装 * HTMLテンプレートをデザイナーが作成
  • 50. CGI * CatyのCGI=Catyスクリプト * つまりロジックは書けません * サイトの表面からはロジックを分離
  • 51. CGIの例 * リリース2に含まれるWikiのCGI * どれもこれもワンライナー index.cgi: wikititles / | print index.html edit.cgi: editwiki / | print edit.html post.cgi: postwiki /
  • 52. サイトの設定ファイル * 拡張子毎のデフォルトコマンドを設定できる * が、デフォルト設定でサイトが十分構築できる * よく使いそうなパターンはデモに収録 * URLマッピングの類はない &quot;filetypes&quot;: { &quot;.wiki&quot;: { &quot;is_text&quot;: true, &quot;assoc&quot;: &quot;viewwiki %1 | print page.html&quot; } }
  • 53. サイトの構成は単純 * URLがある=公開ディレクトリにファイルがある o インクルード専用ディレクトリなどはある * 公開ディレクトリやテンプレート置き場を指定 * 覚えることはあまりないです /mysite _manifest.json <- 設定ファイル /pub <-公開ディレクトリ /index.html /forum.cgi /templates <- インクルードやprint経由でのみアクセス /res  <- コマンドの使うデータ置き場
  • 54. 一旦まとめ * 古典的なWebサイトの延長 * 個々の要素は限られた機能を持つ * 単純化による学習容易性 * 機能が限られていれば自然と分業できる
  • 55. Catyの真の姿 * Catyのコア=言語処理系 * 厳密分離の核心がCatyスクリプトにある * その処理系こそがCatyの本質 WebフレームワークとしてのCaty = CatyスクリプトのWebフロントエンド
  • 56. Catyはこんな構成 Catyスクリプト処理系 シェルフロントエンド Webフロントエンド キーボード入力 HTTPアクセス
  • 57. コンソールとWebが対等 caty> print --resolve /index.html = GET /index.html HTTP/1.1 caty> {&quot;path&quot;:&quot;Example&quot;}|/edit.cgi = GET /edit.cgi?path=Example caty> {&quot;path&quot;:&quot;Example&quot;, &quot;content&quot;: &quot;hogehoge&quot;} | /post.cgi = POST /post.cgi HTTP/1.1 path=Example&content=hogehoge
  • 58. Catyスクリプトの仕様書 pipeline -> term ('|' term)* term -> scalar | command | object | list | functor | tag | when | '(' term ')' scalar -> string | integer | number | boolean list -> '[' pipeline (',' pipeline)* ']' object -> '{' item (',' item)* '}' item -> string ':' pipeline command -> symbol option* (symbol|scalar)* symbol -> ('a'..'z' | 'A'..'Z') ('a'..'z' | 'A'..'Z' | '0'..'9' | '_')* tag -> '@' string | symbol option -> &quot;--&quot; symbol symbol | scalar functor -> symbol '{' pipeline '}' when -> &quot;when&quot; '{' case (',' case)* '}' case -> symbol | string &quot;=>&quot; | &quot;==>&quot; pipleline
  • 59. 改めてCatyスクリプトを説明(1) * あくまでもテンプレートとホスト言語の仲立ち * Unixのパイプの発想 * ネイティブデータはストリームではなくJSON * スーパーバイザーとデザイナーが対象に入る * プログラマが書いても悪くはないよ?
  • 60. 改めてCatyスクリプトを説明(2) * JSON構文はそのまま使える &quot;string&quot; [1, 2, 3] {&quot;name&quot;:&quot;鍬田力&quot;, &quot;job&quot;:&quot;自称料理研究家&quot;} * JSON構文にコマンドを入れ込める print /index.html [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;] | concat { &quot;blogTitles&quot;: blog:recentBlogEntries , &quot;wikiTitles&quot;: wiki:recentUpdatedWiki }
  • 61. 改めてCatyスクリプトを説明(3) * タグディスパッチによる分岐 loggedin --as kuwata | when { OK => print -e /secret.html, NG => &quot;/login.html&quot; | redirect } * Catyでは任意のデータにタグが付けられる @person { &quot;name&quot;:&quot;檜山正幸&quot;, &quot;job&quot;:&quot;キマイラ飼育記の中の人&quot; } * object型にpersonというメタ情報が付く * メタ情報が付いた型は元の型とは違う
  • 62. 改めてCatyスクリプトを説明(4) * 繰り返しの代わりのeach(map関数) [&quot;foo&quot;, &quot;bar&quot;, &quot;buz&quot;] | each {toupper} 通常使うCatyスクリプトの要素はこれで全部
  • 63. 余談:普通は使わないコマンド * テストの実行時のみ有効なコマンド: eval [&quot;print /index.html&quot;, {...}] | eval = {...} | print /index.html * 通常のコンソールやWebでは使えません * その理由は……
  • 64. こんな事が書けてしまう test:list-testfiles / | each { { &quot;testcase&quot;: pass, &quot;testresult&quot;: ( [&quot;readFile --readfrom testfiles &quot;, pass] | concat | [pass, &quot; &quot;] | eval | [pass, &quot;&quot;] | eval | each { { &quot;command&quot;: getpv command, &quot;results&quot;: [{&quot;command&quot;: getpv command, &quot;data&quot;: getpv data}, findpv setup, findpv teardown] | [ nth 1 | when {EXISTS => [pass, &quot; &quot;] | eval, NO => pass}, nth 0 | [getpv command, getpv data | unzip | nth 0, getpv data | unzip | nth 1] | [[nth 0, nth 1 | length] | repeat, nth 1, nth 2] | [[nth 0, nth 1] | zip | each {eval}, nth 2] | zip | each { eq | when { &quot;Same&quot; => &quot;[OK]&quot;, &quot;Diff&quot; => [&quot;[NG] &quot;, toString] | concat, } } | enumerate, nth 2] | [nth 2 | when {EXISTS => [pass, &quot; &quot;] | eval, NO => pass}, nth 1] | nth 1 } } ) } | expand testresult.txt } | concat | chop
  • 65. さらなる悪夢 &quot;[pass, pass] | eval&quot; | [pass, pass] | eval * 無限に再帰します * ってか Y コンビネータです * 即ちチューリング完全
  • 66. チューリング完全性との戦い * あくまでもCatyスクリプトは低機能が第一義 * あまりパワフルだと弊害が多い o 静的検証への悪影響 o 安全性への悪影響 o そもそも使うのも学のも難しくなる * ただし、evalが必要なケースがある o テスティングフレームワーク
  • 67. Catyスクリプトの型 * パイプは確かに気軽に使える * でも繋げるコマンドを間違えることもある * 可能な限り実行前に検出したい JSONスキーマによる型付け
  • 68. JSONスキーマの基本型 * スカラー型 string, binary, integer, number, boolean, null * 配列・リスト・タプル型 array [integer, string*], list[string], tuple [string, integer] * オブジェクト型 object {&quot;name&quot;: string, &quot;job&quot;: string, &quot;age&quot;: integer} * 特殊型 any, never, void * 型変数 _S, _T, _U...
  • 69. JSONスキーマの型構築子 * |:ユニオン型 o string | null で「stringあるいはnull」 * &:インターセクション型 o A & B で「A, B両方の要素を持つ」 o object にしか使えません * ?:オプショナル型 o object {&quot;name&quot;:string, &quot;email&quot;:string?} o &quot;email&quot;プロパティがないかも * @tag:タグ o @person {&quot;name&quot;:string, &quot;age&quot;:integer}
  • 70. JSONスキーマの例 type httpResponse = object { &quot;header&quot;: { *: string }, &quot;body&quot;: string | binary, &quot;status&quot;: string, };
  • 71. スキーマによる型付け * あらゆるコマンドは入出力の型を持つ * コマンド同士の結合時には型チェックがされる o 今はちょっと適当 o そのうちきちんと実装します * 型チェックの基準 o A | B の結合が成立する条件 o Aの出力型がBの入力型に包含されている * 型変数を導入したので多相コマンドが書ける * 型変数は型推論されて型チェックされる
  • 72. 今日は説明しませんでしたが * コマンドの型を指定するための機構もあります * そちらはDIの宣言にもなってます * 宣言しないとファイル・DB・セッションなどへのアクセスがほぼ不可能です * 宣言時に読み込み・書き込みの指定もします * つまり、型宣言をみれば副作用の有無がわかります
  • 73. まとめ * フロント部分は素朴な構造 o 学習容易性が大事 o 限られた機能で自然な分業 * バックはガチガチに定式化 o 宣言的な仕様の記述 o 強い型システム
  • 74. ご清聴有難うございました