Upgrade to Pro — share decks privately, control downloads, hide ads and more …

continuation_web_framework_scheme.pdf

 continuation_web_framework_scheme.pdf

Niyarin

July 25, 2019
Tweet

More Decks by Niyarin

Other Decks in Programming

Transcript

  1. 継続と
    アプリケーション
    (Schemeのオレオレ・Toy・Webフレームワークの紹介)
    Niyarin

    View full-size slide

  2. オレオレ・Toy・WebFrameworkを作っています
    ・継続ベース
    ・プロトタイプ/学習用なのでセキュリティ、その他はてきとう
    ・未完成
       niyarin/oreore-toy-webframework-scm
    継続ベースのWebフレームワークはそれなりにある
      GaucheのKahua
    Ypsilonのlunula
    RacketのWebFramework
    etc. 1

    View full-size slide

  3. 継続とは(てきとう)
    特徴
    ・ジャンプ
    ・値を渡せる
    ・状態を保持
    (+ 1 (call/cc (lambda (c) (c 2))) 3)
    ;6
    (define out-c #f)
    (+ 1
    (call/cc
    (lambda (c)
    (set! out-c c)
    (c 2)))
    3)
    (out-c 100)
    ;104
    2

    View full-size slide

  4. 継続をWEBアプリケーションに使う1
    ・セッションの保存
    .
    .
    .
    リクエスト1
    レスポンス1
    リクエスト2
    レスポンス2
    クライアントA サーバー
    クライアントA
    name Taro
    old 30
    セッションデータ
    (let ((name “Taro”)
    (old 30))
    (call/cc
    (lambda (cont) ;contにセッション情報をのせる
    body …)))
    3

    View full-size slide

  5. 継続をWEBアプリケーションに使う2
    ・ページの遷移
    localhost:8080/piyo?a=1&b=2
          ↓
    (…
    (call/cc
    (lambda (piyo)
    (set! piyo-page cont)))
    …);遷移先のページ
    (piyo;遷移時に継続を呼び出す
    ‘((a 1)
    (b 2)))
    4

    View full-size slide

  6. コード紹介1:継続を使うと自然な記述ができる
    (define (index-page param)
    (let loop ((uname "")
      (password ""))
    (let ((loginpage-data
    (call/cc
    (lambda (cont)
    (render
    `(ログインページ ))))))
    (cond
    ((not (validation loginpage-data))
    (loop
    (get ‘uname content)
    (get ‘password content)))
    (else
    (render `(OKページ))))))
    sample/sample.scm(一部省略)
    (define (index param)
    (let loop ()
    (let ((data (read)))
    (cond
    ((failure? data)
    (loop))
    (else
    (display “OK”)))))
    同じ構造のプログラム
    5

    View full-size slide

  7. (otw-render-view
    `(html
    (body
    (div (@ (style "color:#ff0000"))
    ,error-message)
    (form (@
    (action
    ,(otw-generate-uri cont))
    ;生成結果=> piyo?contid=1
    (method "post"))
    (input (@ (type "text")
    (name "uname")
    (value ,uname)))
    (input (@ (type "password")
    (name "password")))
    (input (@ (type "submit")
    (value "Submit"))))))
    コード紹介2:どのように継続を渡すのか
    ID-継続の組で管理して、IDのほうを渡している
    ※ URLにID埋め込んでいるが、セキュ
    リティ的には✗
     =>継続ハイジャック
    6

    View full-size slide

  8. 実装中バグらせた話
    (define (index-page param)
    (let loop ((uname "")
      (password ""))
    (let ((loginpage-data
    (call/cc
    (lambda (cont)
    (render
    `(ログインページ ))))))
    (cond
    ((not (validation loginpage-data))
    (loop
    (get ‘uname content)
    (get ‘password content)))
    (else
    (render `(OKページ))))))
    1. 赤い部分で止める必要がある
     なにもしないと、青い領域に入る
    ・render内で大域脱出する
     ・限定継続ベースにするのも手
    2. 2つは違うリクエストなので、レスポン
    スを出力するポートは別
     ・レキシカルな場所(左だとparam)におく
    と継続に補足される(古いポートが参照さ
    れる)
     ・外でスレッド-portで管理している
    7

    View full-size slide

  9. ・継続を使うとWebアプリケーションを自然にかける
    ・いつか正式にリリースしたい
    終わり

    View full-size slide