Block Rockin’ Codes

back with another one of those block rockin' codes

なぜ html の form は PUT / DELETE をサポートしないのか?

注意

内容については一切保証しません。

ここでは、主に W3C ML での議論や各種仕様などに基づいて書いています。 ここに書かれていることが正しいかどうかは、自身で判断して下さい。 事実としておかしいところなどは、コメントでどんどん指摘して下さい。遠慮はいりません。

ただし、このエントリでは「form が PUT/DELETE をサポートするべきかどうか?」の議論はしません。 「REST の是非」や「PUT/DELETE の意義」についても議論する気はありません。 ここでやっているのは、あくまでもどういった議論の末現状があるのかの調査です。 そうした意見がある場合は、 W3C などに投稿するのが最も有益だと思います。

History

  • 2014/03/29: 公開
  • 2014/03/29: XForm と XHTML の関係を明確化(thanx koichik)
  • 2014/03/29: HTTP/1.1 と XHTML1.1 の時間関係を明確化、それにより HTML3.2 の項は大幅修正 (thanx koichik)
  • 2014/04/09: HTML Form Extension のサンプルを追加
  • 2014/04/10: Cameron 氏とのメールやり取りの結果、「今後」がわかったので追記
  • 2014/04/10: 関連エントリをリンク

Intro

HTML の Form は「歴史的経緯」だとか「セキュリティ的な理由」
により GET と POST しかサポートしない、
というよう分かったような分からないような説明はよく見るけど、
実際は何故なのか。

というのが話の始まりで、それを事あるごとに調べようとするけれど、よくわからずにいました。

ということで呟いてみたところ、色々な方から反応を頂きました。 その反応については、以下にまとめています。

なぜ html の form は PUT / DELETE をサポートしないのか? - Togetterまとめ

f:id:Jxck:20140329075224p:plain

わかったことは、過去についてはそこまではっきりと書かれたリソースはなさそうなこと。 そして、色々な条件が重なって、現在の仕様に落ちつているようであること。 また、新しい仕様についての提案はあり、議論はまだ続いているということ。

ここまでの話をあらためて調べて、まとめてみました。

前提

今回話題にしたいのは、 HTML の form の仕様が HTTP のメソッドの "GET", "POST" 部分しかサポートしていない理由です。

具体的には以下の method 属性です。

<form action="http://example.com/users" method="post">
   <label for="name">name: </label>
   <input type="text" id="name">
   <input type="submit" value="send">
</form>

HTTP/1.1 では、メソッドとして以下の 8 つを定義しています。

GET
POST
PUT
DELETE
HEAD
OPTIONS
TRACE
CONNECT

この中で実質リソースの操作に用いられるのは GET, POST, PUT, DELETE の 4 つです。

REST の考え方が普及して以降は、この 4 つのメソッドを用いてリソースの操作を実行する API を提供するサービスも増え、プログラム間の通信や、 Ajax を用いたリクエストでは PUT/DELETE を用いた操作は実際に行われています。

しかし、 HTML の Form は GET/POST 以外をリクエストすることができません。 そこで現状は、 POST リクエストに hidden 属性で _method パラメータを付与したり、 submit イベントを JavaScript でフックして、 Ajax で PUT/DELETE リクエストを代行するなどの方法で回避されています。

時系列

今回の件は、仕様の時系列にも関係があるので、まとめてみました。 各仕様は、 IETF, W3C などそれぞれのワークフローで更新されており、下記はその主だったバージョンのみを載せています。 

仕様(HTTP)

HTTP の各仕様を見てみます。

PUT/DELETE という method が最初に出てきたのは HTTP/1.0 です。

http://tools.ietf.org/html/rfc1945#appendix-D.1

これは、 appendix の Additional Request Methods 扱いです。 ここでは PUT, DELETE, LINK, UNLINK があり、独自拡張としてこれらのメソッドの実装があったため、その注意を促す目的だったようです。(実際どの実装だったのかは、わかりません。)

HTTP/1.1 からは intro で紹介した 8 つのメソッドが定義され、 PUT, DELETE は正式な HTTP メソッドになりました。

仕様(HTML)

HTML の各仕様を見てみます。いずれも Form の method には GET/POST しか定義されていません。

HTML3.2 http://www.w3.org/TR/REC-html32#form

method
When the action attribute specifies an HTTP server,
the method attribute determines which HTTP method
will be used to send the form's contents to the server.
It can be either GET or POST, and defaults to GET.

HTML4.0 http://www.w3.org/TR/1998/REC-html40-19980424/interact/forms.html#adef-method

HTML4.01 http://www.w3.org/TR/html401/interact/forms.html#adef-method

method = get|post [CI]
This attribute specifies which HTTP method
will be used to submit the form data set.
Possible (case-insensitive) values are
"get" (the default) and "post".
See the section on form submission
for usage information.

HTML5 http://www.w3.org/TR/html5/forms.html#attr-fs-method

The method and formmethod content attributes are
enumerated attributes with the following keywords and states:

The keyword get, mapping to the state GET,
indicating the HTTP GET method.

The keyword post, mapping to the state POST,
indicating the HTTP POST method.

HTML3.2

HTML3.2 のドラフトには、参照する HTTP のバージョンは明記されていないようです。 しかし、 HTTP/1.1 が出たのは HTML3.2 のたった 2 週間前であるため、現実的には HTTP/1.0 を参照していたとかんがえるのが妥当でしょう。

少なくとも、その 2 週間の間で PUT/DELETE の存在を意識した上で HTML3.2 の仕様に取り込まなかったというよりは、 PUT/DELETE の存在は一旦おいておき HTTP/1.0 ベースで HTML3.2 の仕様を(ほとんど決まっていたものを)出したという方が自然だと考えられます。

PUT/DELETE にしても、 HTTP/1.0 から存在はしており、それを HTTP/1.1 で採用するかは 1996 年後半ではもう議論に上がっていただろうし、 HTML3.2 の議論をしている側も完全に知らなかったということは無いでしょう。

ここは、 HTML3.2 は HTTP/1.0 をベースとし、 HTTP/1.1 への追従は後のバージョンで行う。 とするのが妥当な判断だっただろうと想像できます。

よって、問題は次のバージョン HTML4 に移ります。

HTML 4.0, 4.01

HTML4.0 からは、 HTTP/1.1(RFC2068) への参照が明示されています。つまりここからが HTTP/1.1 を前提に Form に PUT/DELETE を入れないことを選択したドラフトと言えるでしょう。

http://www.w3.org/TR/1998/REC-html40-19980424/references.html#ref-RFC2068

HTML4.0 は HTTP/1.1 が出てから 11 ヶ月後、 HTML4.01 は 2 年空いています。 しかし、該当部分の仕様はいずれのバージョンも変更がありません。

ここの期間には謎が多く、実際に「Form に PUT, DELETE を入れるべきか?」という議論が、あったのかどうかもわかりません。(見つけられませんでした、見つけた方は教えて下さい)

しかし、この時代(1997~1999) は、まだ WebDAVAjax、 REST の論文などは出ておらず、 PUT/DELETE によって何かを行うという需要がそこまで強くなかったのでは無いかと考えられます。

また、1997/4/4 には、 Apache HTTP Server の開発者から Apache HTTP Server に PUT を実装する場合の、セキュリティ的なリスクや、それを回避するために試行錯誤した結果が紹介されています。

Publishing Pages with PUT

ここで紹介されている手法は、あくまで「新規文書をサーバに置く(PUT)」というユースケースであり、Netscape Navigator Gold, AOLPress, Amaya という、オーサリング機能を備えた当時のブラウザが PUT をサポートしたことが読み取れます。

Apache でもまだ、実装の面でそこまでこなれていなかったことや、 Web ページの編集という、今の Ajax などと比べると限定的なユースケースからも、 PUT というものが、まだそこまで広く使われていたものではなかっただろうことが想像できます。

なお、当時ブラウザの開発に携わっていた @ さんにお聞きしたところ、やはり積極的な人がいなかったという雰囲気だったようです。

XForms

HTML では、仕様に取り込まれることがなかった PUT/DELETE ですが、実は XForms という仕様には 1.0 で PUT が、 1.1 で DELETE が追加されていました。(XForms 1.0 には 2nd, 3rd Edition がありますが、該当部は変わっていません。)

  • 2003/11/14: XForms 1.0 (GET, POST, PUT)
  • 2009/10/20: XForms 1.1 (GET, POST, PUT, DELETE)
  • 20xx/xx/xx: XForms 2.0(策定中) (GET, POST, PUT, DELETE)

XFormsXML を用いて、よりリッチな機能を持つ Form を実装するための仕様です。 XHTML2.0 には XForms が含まれる予定だったため、 XHTML2.0 が主流となっていればそれが使えたかもしれません。 しかし、 XHTML2.0 は策定活動が 2012/12/17 で終了しました。また XForms を実装しているブラウザは無いため、これらの機能は使うことができません。

HTML5

2010 年に、 HTML5 の仕様として、以下のスレッドでこの件に関する議論が行われました。 issue は HTTP の策定活動にもコミットしている Julian Reschke 氏です。

Bug 10671 - consider adding support for PUT and DELETE as form methods

これは Ajax が主流になって以降であり、かつ Rails などを中心に REST が普及した後です。 しかし、問題の提起は「Form に PUT/DELETE を入れよう!」という短絡的なものではなく、より慎重なもののようです。 Julian 氏の発言の一部を抜粋します。

#c0(最初の発言)

It seems that we currently do not understand how
PUT and DELETE will be useful for HTML forms.

For DELETE, it's indeed easy to create a useful request.
However, server implementations usually respond with 200
and a minimal response body ("deleted")
or 204 (no content).
So it's not clear how this can be used in a web application.

For PUT, it seems there's no real use case as long as
the web page doesn't have full control
over the payload, and also can set the content type.

Please consider removing this feature until there's a clearer
understanding about what it's good for.

#c5

The tricky question is how to actually *use*
PUT and DELETE with HTML forms.
The bug was raised because I think the spec (as it was back then)
wasn't specific enough to make this work,
and thus early adoption (such as in FF4) would
make it very hard to do the right thing later on.

PUT や DELETE を Form でサポートする前に、サーバとのインタラクションや Form では HTTP ヘッダなどが変更できない点につていて、まだ Form の仕様自体にキチンと解決すべき問題があるという、問題提起が主のようです。

しかし、この議論は Hixie こと Ian Hickson によって突然 Reject されます。

#c16

Status: Rejected
Change Description: no spec change
Rationale: PUT as a form method makes no sense,
you wouldn't want to PUT a form payload.
DELETE only makes sense if there is no payload,
so it doesn't make much sense with forms either.

DELETE はペイロードを必要としないし、 Form のデータを PUT したいわけではない。 Form でこれらをやるのは make no sense であるとしています。いわゆる Wont' Fix という感じです。 2011/12/2 のことでした。

HTML Working Group

ところが、この議論は 2011/12/7 に public-html-comments という別の ML で再発します。

Follow-up about PUT and DELETE in form methods

どうやら ML 初心者のようで「先週のあの議論、どうなったの?」という感じの質問です。 しかも、 bug 10671 で一度も指摘されていなかった Mike Amundsen という人の以下のドラフトが参照されています。書かれたのは 2011/4/1 、つまり 10671 の議論の最中ですね。

Supporting PUT and DELETE with HTML FORMS

この Follow-up about PUT and DELETE in form methods はかなり長い議論になり、そこでは具体的な仕様に落としこむために必要な Form の拡張などについて議論されていたようです。

それがひと通り終わった 2012/1/14 に Julian 氏は HTML Working Group に二つの issue を上げます。

タイトルの通り、 HTML の Form を HTTP のリクエストに対して拡張するための議論と、 HTTP のレスポンスに対するユーザエージェントの挙動についての議論です(こちらは、前段としてブラウザごとの挙動の調査もあります)。

いずれの issue も CLOSE されており、 ISSUE-195 については以下の結果がみつかりました。

前者は Cameron Jones 氏のもので、 Form を拡張する提案(proposal) がなされています。 後者は Edward Oconnor 氏のもので、 Cameron 氏の提案の複雑性や実装時の懸念などを指摘しているようです。

また ISSUE-196 の最後 で Cameron 氏はこの提案をより具体化した Unofficial Draft を 2013/2/22 に作成し Github で公開しています。

HTML Form HTTP Extensions

このドラフトが、現時点で追えた最後の議論の結果です。少し見てみます。

HTML Form HTTP Extensions

http://cameronjones.github.io/form-http-extensions/index.html

このドラフトでは、 Form から、生成される HTTP リクエストをより柔軟に変更できるように Form の拡張を行う仕様です。 PUT/DELETE のサポートという狭い範囲ではなく、本質的に Form に足りていなかった機能を拡張しています。

たとえば payload 属性を追加することで、 Form から HTTP のヘッダ情報を追加できるようにすることで、単に method が PUT/DELETE その他をサポートするだけでは解決できなかった問題にも対応できるようにしています。

ドラフト中の PUT と DELETE のサンプルを見てみます。

<form action="http://www.example.com/cms/hogmanay" method="PUT">
  <input name="If-Unmodified-Since"
         type="hidden"
         value="Tue, 1 Jan 2013 12:00:00 GMT"
         payload="_header"/>
  <textarea name="content">
    // content
  </textarea>
  <button type="submit">Update</button>
</form>
<form action="http://www.example.com/logs" method="DELETE">
  <label for="since">Since</label>
  <input name="since" type="datetime"/>
  <button type="submit">Delete</button>
</form>

DELETE は割りとそのままな感じですが、 PUT は input タグの payload 属性を用いて直接 HTTP ヘッダを追加しています。

他にも、ヘッダを触れるということは Bacis 認証が Form だけで(ブラウザ組み込みの UI ではなく)できます。 実際には、専用の username, password を使用します。

<form action="http://www.example.com/login" method="POST">
    <label for="_username_">Username</label>
    <input name="_username_" type="text"/>
    <label for="_password_">Password</label>
    <input name="_password_" type="password"/>
    <button type="submit">Login</button>
</form>

また、メールの送信も定義されているようです。

<form action="mailto:">
    <label for="to">To</label>
    <input name="to" type="email" payload="_action"/>

    <label for="cc">Cc</label>
    <input name="cc" type="email" payload="_header"/>

    <label for="bcc">Bcc</label>
    <input name="bcc" type="email" payload="_header"/>

    <label for="subject">Subject</label>
    <input name="subject" type="text" payload="_header"/>

    <label>Content</label>
    <textarea size="50"/>

    <button type="submit">Send</button>
</form>

結構な拡張ですね。

今後

Cameron 氏のドラフト以降、この議論は止まっているようで、特に 2013年後半くらいからの議論は見つかりませんでした。 現状どうなっているのかがわからず、 Cameron 氏のドラフトについても扱いがよくわからなかったため、本人にメールで質問をしてみました。

いきなりの質問でもそこは標準化ガイ、快く返してくれました。 それによると、以下のような感じ。

  • このドラフト自体は、完成している(出せる状態である)という認識。
  • HTMLWG への提出はまだしてないけど、もう少し頑張ってそこまでもっていきたい。
  • 近いうちに FPWD(First Public Working Draft) として ML に提出する予定。
  • HTML5.0 の策定プロセスに乗せて、実際には HTML5.1 あたりで入れたい。

ということで、近いうちにこのドラフトが ML に投稿されて、そこでまた今回の話を含めた Form というもの自体の今後についての議論が起こることと予想されます。 Cameron 氏は、投稿時には BBC に自分を入れてくれるとのことなので、動きがあったらまたここにアップデートを書きたいと思います。

まとめ

まとめると、以下のような感じかと思います。

  • HTML4.x 以前: 需要があまりなく、積極的に仕様に追加する人もおらず、 HTTP3.2 からの仕様を引き継いでいた。
  • XForms: 仕様には取り込んだが、それを含む予定だった XHTML2.0 の策定が終了し、普及しなかった。
  • HTML5: 議論は何度かあり、現在 Cameron 氏のドラフトあたりが有力で、これはそのうち ML に投げられる模様。
  • HTML5.1?: Cameron 氏のドラフトが議論され、承認されればこの辺で入るかもしれない。入らない可能性は大いにあると思われる。

Cameron 氏のドラフトについて意見がある場合は、 W3C の ML などを通じて Cameron 氏にフィードバックすることで、今後の議論に寄与することができると思います。

最後に、再度書きますが、もし何か間違いなどがあったら遠慮なく指摘して下さい。 必要なものについては追記し、アップデートします。

今回の調査にご協力いただいた皆様、本当にありがとうございました!

関連リンク

Jxck

そうだ、と思い立って京都で Go のハンズオンしてきました。 #gokyoto

Intro

東京であったとある勉強会で、 @ さんに「京都に来てください」と言われたので、「高倉二条連れてってくれるならいいです」 と二つ返事で引き受けたので、タイトルの通り京都にいって Go のハンズ・オンしてきました。

Go勉強会 そうだ京都、行こう

ハンズオン資料

想定レベルは、他の言語経験はあるけど Go は初心者であること。 前提としては、環境構築済みで Tour Of Go の演習以外をひと通りやってること。 として、資料を作成しました。

基本的には、各言語仕様を細かく見るというより、とにかく手を動かして動くものを作っていくパターンです。 その方がやってて面白いしね。

テーマはタスク管理ですが、それはおまけで、 Go の言語仕様と標準モジュールをガンガン触りながら、イディオムや考え方を解説していきました。

資料は以下に公開しています。

https://gist.github.com/Jxck/9551539

京都観光

初日ハンズオンの前に、なんとかたつさんが行く行く詐欺し続けたことで有名な高倉二条に。

ネットの怖い人からムチャぶりが。

二日目は初心者になりすましてハンズオンに混ざっていた @ さんの紹介で、はてなの @ さん、 @ さん達とお会いしてきました。

京都といえばはてな。よく考えると自分はかなりお世話になっているサービスの一つ。 あと、今のはてなは思っていた以上に平均年齢が低いようだ。

とりあえず高倉二条と似た「すがり」というお店に。ラーメンの写真は撮り忘れた。

その後、はてなのオフィスにおじゃますることに。初はてな

途中で東京で JAWS に出ていると思っていた @ さんが出社してきてびっくりしたなど。

良くある京都観光的なことは一切しなかったけど、良い旅でした。 @ さん、参加者のみなさん、はてなのみなさんありがとうございました!

Log

IETF89 で #http2study の話をしてきました。

Intro

2014/3/2 ~ 3/7 にイギリスのロンドンで実施された IETF89 に参加し、HTTP2 について議論している httpbis というワーキンググループで、日本での HTTP2.0 に関する Local Activity (コミュニティ活動とその成果)について発表してきました。

IETF

IETF は、ネットに関わる「Wire より上、Application より下」のレイヤの標準仕様などを決める標準化団体です。 IETF には、さらに目的に特化した WG(Working Group) に分かれており、最近自分が取り組んでいる HTTP2 はこの IETF の中の httpbis という WG で議論されています。

今回色々な方の助けもあり、幸運が重なって、初めて IETF に参加することができました。

とりあえず旅行記的に書いてみます。

-2日目(出発)

日本での土曜の早朝の便なので自宅からは始発でもキツイ、ということで前日終電で羽田に入り、空港で一晩明かすことにしました。 結構人がいる静かな空港のカフェで、ひたすらスライドとコードを書きます。

飛行機に乗ったら離陸と同時に爆睡。 12 時間のうち 10 時間は寝て、 2 時間は "Kick Ass 2" を見てるうちに到着。 起きた時はイギリスの 8:00 くらいだったので、時差ボケ一切なく英国入りするという狙いは完全に成功しました。

-1日目(入国)

FB には書きましたが、「個人が趣味で IETF に参加する」というシチュエーション自体が怪しまれたのか、税関を通るのに苦労するという罠を何とか突破しホテルへ。

飛行場から Heathrow Connect (8.5ポンド)で行くつもりが、間違えて Express (21ボンド) を買ってしまい宿へ。快適でした(泣。

宿は会場から 2 駅離れた Baker Street 付近。普通のホテル。

近くにはでかい公園とかシャーロック・ホームズミュージアムとかあったけど、ほとんど観光せず。先に現地入りした方と合流。 IETF 大先輩な方々と、トルコ料理を頂きました。

0日目(New Commers Session)

IETF 開始の前日にあたるこの日は、参加受け付けをし、初心者向けのセッションへ。

New Commer は、受付で赤いリボンをもらうことができ、このリボンをつけている限りはみんなが優しく接してくれるそうです。

そして、 New Commers Session に参加。 IETF がどういう団体で、どういうプロセスで標準仕様を決めているのか、などなど細かいところまで教えてもらえます。(資料はまだ上がってないみたい) これ、凄い勉強になったし、噂の hum デビューしました。

(IETF では Rough Consensus を取るときに、挙手させるのではなく hum (ハミング) で大体の賛否を取ります。 要するに「hu~~~~」って感じでハミングして、だれが何に賛同しているかを見た目ではわかりにくくしている。)

その後 Orientation で IETF な方々や他の参加者と交流。意外と日本人が多い、特に大学生が多い。

ここで、今回参加しないと聞いていた WebSocket over HTTP2 の仕様作者さんが急遽参加していたことを知り、一緒に御飯を食べることに。

1日目(httpbis#1)

httpbis の一回目のミーティング。 このミーティングの最初の方が、自分達が話すターン。

今回の httpbis は、 Google の Hasan というピンクを着こなすオシャレガイにより、「スーツに Bowtie」というドレスコードが発行されていました。 実際、全員ではないけど Chair の Mark や Google の Martine, Will Chan などなど数人がスーツで出席。

俺は、 @ と一緒にスーツで登壇。

まず自分が #http2study などで行っている日本の Local Activity や、その成果としての hpack-test-case について話し、最後に @ が 4 月に書く予定の I-D (Infomational Draft) について話しました。

その後は、 Github の issue を Open Mic で話しながらみんなで閉じるという、 IETF の歴史からいうと結構先進的なワークフローで議論が進みました。

注目していた WebSocket over HTTP2 の話はあまり出ず。 hum をする機会はありませんでした。

ひと通り WG が終わったら、最後に全体向けのプレナリセッションがあり、今話題の Bitcoin の話とかあったのですが、その寸前に httpbis 議長の Mark が、地元の勉強会に出るらしいことを聞きつけ、自分だけそっちに行きました。

Mark のセッションは俺にとってはそんなに新しいことはなかったけど、会場からはかなり質の良い質問が沢山でていて、勉強会としては非常に良かったと思います。(電源が無いことは別として)

日本(の Otaku 文化)大好きなナターシャと、カウボーイ・ビバップ図書館戦争の話をしたりしながら、ひと通り飲んで帰宅。

2日目(social)

イギリスに来たら必ずやる「イングリッシュ・ブレックファースト」で朝食。

好きである。ちなみに紅茶派。

この日は特にミッションも無かったので、 WebRTC とか見ていたけど、席も後ろで殆ど見えず、ついていけなかったのでこのブログをひたすら書く内職。

夜は Social Event ということで会場から 30 分の博物館を貸しきってイベント。

もともとは、造船所だったっぽい。イギリスの歴史についての展示がメインでした。

楽しかったけど、腹ペコなのにフードが圧倒的に不足していて、割りと空腹なまま宿に帰って寝る。

3日目(httpbis#2)

httpbis の二日目。

初日同様に github の issue を片付けていく感じ。 メインだったのは Priority Leveling と、 TLSネゴシエーション周り。

終わり際に少し Mark に話をしたけど、「続きは土曜に」ということで断念。 (土曜は London の Mozilla で非公式の httpbis meeting がある。俺は出れない)

その後何人かで、 1日目に日本のアニメ話をした Natasha にパイの美味しいお店に連れてってもらい、たらふく食べる。

夜のロンドンをちょっと観光案内してもらいつつ解散して宿に帰り、この記事を書く。 また、徹夜で電車に乗り空港へ。

4日目(帰国)

朝の 5 時にチェックアウト。

100ポンド持って行った残りが、空港についてスタバで一杯飲んだ時点で 3 ポンド強の使い道を探るなどする。(空港でお土産を買えば、小銭全部+残りはカードみたいなのが出来たらしい。)

安眠確保のために、奮発してプレミアム・エコノミーに上げたけど、「あれだけ追加払ってもこんなものか。。」という程度だった印象。そうこうするうちに着陸。

そのまま空港で IETF での発表時に着た、およそ社員が会社に着ていくとは思えないドレス・スーツに着替えて出社。何事もなかったように日常にジョインしてターンエンド。

感想

やっぱりまだまだ英語力、特にリスニング力が足りないなぁと。

議論の内容が聞き取れないと自分がどんなにその技術や議題を理解していても、参加できないという現実。

以前 US で NodeConf に参加した時も同じことを思って、自分なりに色々訓練したつもりだったけど、まだまだダメでした。

この状況はもっと何とかする必要がありますね。

あと、標準化の世界は自分にとってはかなり未知で、その世界の仕組みについては標準化 Guy である @ さんとか @ さんに色々教えてもらえたのが幸運だった。

みんなミッションを持って来るので、俺のような趣味の延長で来たような人間がウロウロするのはあまり良いことでは無いのかもしれないけど、 @ さんの計らいで、たった 5 分でも日本のアクティビティーを世界に発信するという能動的な参加ができたのは、幸運だったし自分にとってはいい経験だったと思う。

この世界の人々は、「3月で予算が余ったから来たんですよテヘペロ」と口では言っておきながら、「コードを書く」という俺らが得意とする分野のもう一層隣にある、「標準化する」というレイヤから世界を良くしようという、熱意と正義感で貢献している人が集まっていて、とても良い刺激が得られました。

2015年11月には、 IETF が日本の横浜で開催されることが決定しているので、興味のある方は是非参加してみるといいと思います。

終わりに

肝心の HTTP2 の議論と動向については、次回の #http2study で報告します。

今回の旅で知り合うことができた、 WebSocket over HTTP2 のドラフト筆者である @hirano_y_aa さんと、ネットワーク・インフラのエキスパートである @kaname さんにも登壇をお願いしたので、かなり熱い話が聞けると思います。

最後に、ずっとお世話になりっぱなしだった @ さん、 @ さん、 @ さん。本当にありがとうございました。

Jxck

Go の Generator を channel と closure で速度比較(または Go でのアトミック処理イディオム)

追記

この記事は元々 Go のイディオムとして、いわゆるジェネレータの実装がどうできるのかを軽い気持ちで書いただけで、速いから「Closure を使いましょう」などと一言も言ってなかったのですが、一方が channel であったため原子性についての言及がいくつかありました。

自分としては、ローカルのちょっとしたツール(shell の代わりくらい) の中で使ってただけなので、並行性には言及するつもりがそもそも無かったのですが、自分もそうした前提を書いていなかったのにも原因があります。

例えばこの記事が「グローバルシーケンス」の実装例として参考にされ Web アプリにでもコピペされて、バグの原因になったりでもしたらマズイので大幅に追記します。 (正直ロックを使った排他制御はあまり得意では無いですが。。)

Intro

無限に連番を生成するロジックをジェネレータとして組むときに、 Go の場合は二つの方法が考えられます。 Closure を使う方法と Channel を読みだす方法です。

Closure (goroutine unsafe)

まずは Closure を用いた単純な実装をしてみます。

func Closure() func() int {
    i := 0
    return func() int {
        i = i + 1
        return i
    }
}

今回のベンチマークではこの実装が最速です(後述)。 ただし、この実装は複数の Goroutine から呼び出される場合、インクリメントと取得の部分がクリティカルセクションになっています。 スレッドモデルの場合 "スレッドセーフ" といいますが、 Go ではスレッドではないので "Goroutine セーフ" と呼ぶことにします。この例は Goroutine セーフではない実装です。

Closure (mutex locked)

クリティカルセクションを守る方法としては、ロックを取る方法が多くの言語で使われてきました。 Go では、 sync.Mutex を用いてそれが実現できます。

func MutexClosure() func() int {
    var mutex = new(sync.Mutex)
    i := 0
    return func() int {
        mutex.Lock()
        defer mutex.Unlock()
        i = i + 1
        return i
    }
}

sync.Mutex を用いると Lock() と Unlock() を用いて排他制御が実行できます。 操作の前に Lock() を取得し、defer を用いて関数終了時に Unlock() を実行しています。

一般的に、ロックを用いた排他制御を実施する場合、必ずデッドロックに注意する必要があります。 上記の実装では使っていませんが、 Lock()、 Unlock() などが別の Goroutine で実行されていたり、その間に Channel による同期などを別途行っているような場合は特に注意が必要です。

おまけ Closure (atomic increment)

より低レベルの操作については、 sync/atomic パッケージも提供されています。 例えば CAS やアトミックなインクリメントなどが提供されています。

今回の場合、ここまでは int で実装していますが、 int の API はないために int32 を使うことを許容できるなら、今回のクリティカルセクションのロジックが単なるインクリメントであることから、 AddInt32 を用いることができるかも。と思いましたが、これは return がロックされていないのでダメですね。 これを使うなら、ユーザランドでグローバルにある値を直接インクリメントすればいいのかな。

func AtomicClosure() func() int32 {
    var n int32 = 0
    var i int32 = 1
    return func() int32 {
        return atomic.AddInt32(&n, i)
    }
}

また、このパッケージのドキュメント冒頭には以下の説明があります。

These functions require great care to be used correctly.
Except for special, low-level applications,
synchronization is better done with channels or the facilities of the sync package.
Share memory by communicating; don't communicate by sharing memory.

要するに、普通にアプリやツールを書くような用途での使用には推奨されておらず、(明示はされていませんが)より高度な実装で必要なケースに向けて提供されています。

Channel

sync パッケージを全く使用しなくてもアトミックな処理を実装することができます。 Go には channel という言語に組み込まれた MQ のような機能があり、 この channel を使用して、メッセージングにより同期をとる方法です。

func Channel() <-chan int {
    ch := make(chan int)
    go func() {
        i := 1
        for {
            ch <- i
            i = i + 1
        }
    }()
    return ch
}

この実装では外側の Channel() は読み取り専用の channel を返しており、これを持つ側は channel の読み出しを行うことで数値を取得できます。 この i は Channel() 実行時に生成される goroutine の中にしか存在せず、その goroutine と唯一繋がった channel に対しても書込することはできないため、外からは一切操作できません。

また、 channel には make 時に buffer を設定していないため、当時に一つの値しかそこを通ることができません。 つまり、channel に値があればそれが読み出されるまで書き込みはブロックし、 channle に値がなければ書き込まれるまでは読み出しはブロックします。

大量の goroutine がこの channel を保持していて、同時に読み出しでブロックしていても、書き込まれた値は一番最初に読み出しブロックに入った goroutine にしか読み出されません。

こうして、ロックを一切使わずにアトミックな処理が実現できるのです。

ベンチ

ベンチマークを取ってみます。

func BenchmarkClosure(b *testing.B) {
    cl := Closure()
    b.ResetTimer()

    for i := 0; i < b.N; i++ {
        cl()
    }
}

func BenchmarkMutexClosure(b *testing.B) {
    cl := MutexClosure()
    b.ResetTimer()

    for i := 0; i < b.N; i++ {
        cl()
    }
}

func BenchmarkChannel(b *testing.B) {
    ch := Channel()
    b.ResetTimer()

    for i := 0; i < b.N; i++ {
        <-ch
    }
}

実行結果

Mac Book Air (OSX 10.7.5) 1.6 GHz Intel Core i5 Memory 4GB

$ go test -bench .
PASS
BenchmarkClosure        100000000    11.5 ns/op
BenchmarkMutexClosure   50000000     35.3 ns/op
BenchmarkChannel        5000000      251 ns/op
ok  /path/to/bench  6.747s

ベンチマークの実行回数は、ベンチマークソースの中の b.N の値の部分になり、 関数の実行時間に応じて go test コマンドが適宜調整してくれます。 いずれも十分回数実行されているとみなし、 ns/op に注目して一実行あたりの平均実行時間を比較します。 (数回実行したところ、だいたい同じでした)

implimentation time (ns/op) ratio
closure 11.5 1
mutex 35.3 3.07
channel 251 21.8

最後の列が、 closure 実装を 1 とした場合の比率です。 (書き直す前は channel は 50 倍だったのですが、 channel の速度は変わらないのに closure の速度が何故が落ちたので、 20 倍に縮まりました。 元々の記事は、この結果が予想していたよりも大きかったなぁという趣旨でした。)

考察

ちょっとしたツールなどで、 1 つの Goroutine の中でしか使わないような実装であればどれでも構いませんが、 複数の Goroutine が共有する、いわゆるグローバルシーケンサを実装するような場合には、今回の Closure 実装は使えません。

同じことは、シーケンサでなくともグローバルカウンタや、もっと広く言えば複数の goroutine で共有するロジックでは共通です。 しかし、途中で解説したように sync/atomic は、理由がない限り積極的に使うべきでは無いでしょう。

mutex と channel の実装については、今回 7 倍の速度差が出ていますが、 mutex にはロックを伴う排他制御につきものな種々の難しさが、他の言語同様に伴います。

sync/atomic のドキュメントでも出ていた以下はその選択の指針になります。

Share memory by communicating;
don\'t communicate by sharing memory.

これは、意訳すると「メモリの共有(sync) ではなく、メッセージング(channle) でデータの共有をしましょう」という意味で、 Go はこうしたメッセージングによるイディオムを強く推奨しています。

一般的にロックでの排他制御は難易度が高く、デバッグもしづらいという経験則があり、メッセージングを用いた実装がシンプルで堅牢かつ柔軟なプログラミングが可能であるという理由からです。

同様な主張を元にした、 Go の並行処理については以下の様にドキュメント群でも散々言及されています。

一方で channel も、読み出しが競合してデッドロックするなど、慣れないと上手く書けない場合はあるでしょう。 そうした場合は、この辺が参考になると思います。

過去にこのブログでも言及しています。

結論

  • Goroutine をまたがないで、とにかく速度が欲しい場合: Closure
  • 複数の Goroutine から使い、ロックのプログラミングに慣れている場合: Mutex
  • 複数の Goroutine から使い、 Go の思想に則りたい、プログラムをシンプルにしたいetc: Channel
  • 筆者のおすすめ: Channel
  • 前提を書かずに記事を書かない

おまけ

実は Slice や Map の操作もアトミックではありません。 なので、今回行ったようなことを用いて、 Slice や Map の操作を自分でアトミックにする必要があります。 それを含むロジック全体をアトミックにすることもできますが、単体の追加/削除などをアトミックにするライブラリをいくつか作っているので、そのうちそれを紹介します。

ソースコード

使用したコードは以下にあります。

https://gist.github.com/Jxck/9184764

ジェネレータの解説と非同期への適用

update

2014-01-16

ご指摘頂いたので修正しました。ありがとうございます!

https://gist.github.com/Jxck/8380852 は修正済みです。動画の取り直しは勘弁して下さい(汗

-      fn.apply(fn, args);
+      fn.apply(this, args);

intro

あけましておめでとうございます。 今年からはてなブログへ移行しました。

去年末くらいから流行っている Express の後継 Koa では JS の新機能ジェネレータが使われています。 このジェネレータは現在最新の node@11.10 などであれば --harmony-generator をつけることで、有効にすることができます。

今回はこのジェネレータの使いかたと、それを用いてどうやって非同期処理が書き換えられるかを、実演しながら解説したいと思います。

ちょっと長くなってしまったのですが、だいたい以下のような感じです。

  • ~7:00:ジェネレータと yield と next() の使い方と、 next() と yield で値を受け渡す時の注意。
  • 7:00~:ジェネレータで非同期をどうやって縦に書けるか、またエラーはどう処理するか、の解説。

なので、ジェネレータ自体がわかっている人は、 7:00 くらいから見ても大丈夫です。

これを見終わると、今流行?のあのライブラリの仕組みがなんとなくわかるかと。

Movie

how to use generator in node from Jxck on Vimeo.

完成品

https://gist.github.com/Jxck/8380852

まとめ

Generator の特徴は、処理を任意の時点で止めてそこから再開できることです。 これを上手く用いると、非同期処理の実行で一旦止め、コールバックが終了したら再開するということができます。

この時、 yield と next() で値をやりとりできるので、コールバック内でしか触れなかったデータ (err, data など) を、コールバックの外の世界に出すことができるようになりました。すると、これまでコールバックの世界でやっていたことを、わざわざコールバックの中でやらなくて良くなるため、コールバックの中でやるべきことは「コールバックの中で next(data) して、コールバックの外にデータを出す」という定形処理だけで良くなります。

Node の API基本的にコールバックを引数の最後に取るので、これを上手く利用して、ユーザランドではコールバック以外の引数だけを設定し、定形のコールバックのライブラリ側で実行する。この時、コールバックに渡るデータは、 yield の評価結果としてジェネレータ内に戻し、エラーは throw() を用いて、ライブラリからジェネレータ内に戻します。(Generator 内では、 try-cache で取れます)

この、「Generator の世界とコールバックの世界の、データの橋渡し」と「定形コールバックの実行」を行っているのが co です。 そして、それによってユーザランドでは意識しないでよくなるコールバックを、 Node の API から消し去ってくれるのが thunkify です。

補足

ただし、この中で出てくる co, thunkify もどきは、本家のと比べればおもちゃ以下なので、 本家が中で何をやっているのかを知る手がかりとして見て頂ければと思います。 (本家を読むきっかけくらいにはなるかと。)

本当は co は thunkify 以外にも promise を上手く扱えるようになっているので、気が向いたら promise バージョンを撮ってみようかと思ってます。

harmony オプションが解禁されると、選択肢は非常に増えます。 去年は Koa と Angular な年感あったかもしれませんが、自分にとって今年はもう一段下の Object Observe とジェネレータの年になりそうだと思っています。

2013 年をふりかえる

intro

恒例の振り返りです。


去年の年末に「Go で SPDY サーバを書くと」 言った目標を立ててスタートした年なのでその辺が中心だったと思います。
年の初めにちょろっと SPDY のパッチを go.net に投げて、そっからは HTTP2.0 仕様を追いかけながらサーバ/クライアントのインプリなどをしていました。

Input

HTTP2.0 周りを追いかける中で、ネットワーク周りの知識の圧倒的な不足を痛感した。
そのおかげで、今年はアプリケーションよりは、ネットワークプログラミングな年になった気がする。
「若者のプロトコル離れ」が叫ばれていますが、このレイヤを色々と勉強したし、 RFC も色々と読んだ、標準化プロセスにもちょっと参加してみたりした。


ネットワークプログラミングは難しい。 Erlang ずるい。


そして、このレイヤのプログラムを今年ずっと Go でやっていました。
去年までは Node が多かったけど、思えば今年は Node は殆ど触ってないかも。
自分は Go は割りとミドルウェアを書くのに向いてると思っているので、今自分が書きたいものに非常にマッチしていたと思う。


Go の持つ思想は慣れないと難しいし、慣れても難しいところがあるのですが、それを学ぶことが、自分の言語に対する感覚を大きく広げてくれたと思うので、その辺は非常に勉強になった。


この辺は引き続き勉強していきたい。


あとは、 Angular を少しかじった。
やっと Bata Binding による Single Page なアプリの土台が整いつつあると思う。
そんな話は昔良く書いたけど、同時自分は Stream の連結というふうに捉えていて、それは途中で投げて別のこと始めてしまったので、
今一度この辺始めたいなと想う。


Angular vs Backbone みたいな空気あるけど、自分としてはやりたいことができればどっちでも良い。
ただ、 Backbone は行儀良い JS の延長にあって、 Angular は JS の限界を黒魔術で越えようとしているので、趣味でいじるには Angular の方がおもしろい。
ここをうまく土台にして、もっと Reactive Programing の知見にも触れていきたいと思っている。

合わせて WebComponent が素晴らしいと思うので、もっと普及してみんなが Component 沢山公開して、自分のようにデザインとかマークアップが苦手な人がそこに乗っかれると嬉しいなと思う。
将来的なフレームワークは WebComponent との親和性が重要になる気がしていて、 Angular はそこへの意識が高めだと思うので、その点でもよさそう。

また asm.js の登場で、今まで生 JavaScript でもゴリゴリ書けてしまっていた人たちにも、 altjs に手を出す動機ができたので、
自分もそろそろ手を出してもいいかなと思っている。合わせると Angular.Dart とかになるのかな? TypeScript かどっちかかと思ってる。


そんな感じで、来年は今年学んだことを生かして、もう少しアプリのレイヤで色々やりたいと思う。

Output

なによりも、今年は「月に一度は Blog を書く」という目標を、かなり厳しかったけど、なんとかクリアした。


おかげで、はてダの下にある年ごとの月別リンクが、 2010 年以降 3 年ぶりに 1~12 まで全部そろった。
これは気持ちいい。来年もこれを続けたいと思う。理想は無理に絞り出さなくても常に書きたいことがあるくらいの技術的な探求を続けたい。


コード的な意味で言えば、 SPDY は go.net にパッチを投げたきりになっている。HTTP2.0 の Go 実装は一応できたんだけど、その後のバージョンアップに追い付ききれず中途半端になっている。
なんとか年末休み中には Hello World まで行きたい。

ということで、色々揃ったからあとはガガッとやるだけなので、中途半端だったところはもう少し進めたい。


他には今年も色々書き物が多かった。

発表系で、HTTP2.0 や SPDY 関連の発表が多かったため、その辺のスライドは何度か作った。


勉強会やカンファレンスも沢山あった。

  • CROSS2013 次世代 Web セッション
  • 東京 Node 学園 / 学園祭
  • Go コン
  • HTTP2.0 勉強会 / ハッカソン

あたりをやった。


Go 周りでは名前を「思いついちゃったんだから仕方ない」の精神だった。

  • Go研
  • 電車でGo
  • Go羅温泉
  • Go年会


Go 研は今年から始めた研究会なんだけど、今のところ自分の理想の研究会ができている。
しばらくこのまま続けたい。


他にもちょいちょいカンファレンスや勉強会に、参加したり、発表したりした。


書きものとしては

inao デビューさせて頂いた。(WebDBは二回目だけど、初回は別の方だった)


あと、 HTML5Experts.jp に選んでいただいた。
Google が Web を速くするためにやっている Make The Web Faster というページがあるんだけど、 そのページに上がってるプロダクトやプロトコルなどを片っ端から紹介するという無謀な連載を始めることになった。(言い出したのは自分だけどw)


今のところ、おおよそ月一くらいのペースで自由にやらせてもらって4回まできた。
もう少し続けながら、こういう連載でもやらなければ調べることもなかっただろうことを調べていく。
(毎回調べるの結構つらいが、勉強になる。)


一周回って、執筆もまあ面白いかもと思えるようになってきた。
一方で、コード書く時間がやっぱり減るので、その辺のバランスを上手く取りながら、チャンスがあれば続けていきたい。


2014 にむけて

来年はとりあえず CROSS 2014 で次世代 Web セッションをまたやらせていただくことに
なったので、まずはそれを頑張る。(今回もまたものすごく豪華なメンバーに集まっていただけた。)


来年は HTTP2.0 一旦止めて、ちゃんと動く SPDY サーバを Go で作ろうかと思ってる。
あと、今年はレイヤ低めの話が多かったけど、それらを踏まえてもう少しアプリ寄りに改善を加えた感じで、
なにかやっていきたいと思っている。まだ漠然としている。


あとは、 jxck.io ドメインを運用し始めたので、そろそろはてダは卒業しようかと思っている。


ということで、今年も色々な方に出会えて色々なことを学べて、非常に満足度の高い一年だったと思います。
来年もどうぞよろしくお願いいたします。

これからの Web の話をしよう。 (次世代 Web セッション @ CROSS2014)

Update

2014-01-19 振り返り

CROSS2014 が無事終了しました。

以下ログです。ビデオは前のセッションとかぶっているので 35 分くらいからが本セッションです。


去年に引き続き、今年もなかなか密度の高い内容になったんじゃないかと思います。

プロトコル編では、普段なかなか表に出てこない方を中心にお呼びして、2013 年から今日までの流れを踏まえつつ、今起こっているプロトコル的な変化を浮き彫りにし、今後の HTTP2.0 の展望や QUIC の持つ意義などを話し合いました。
象徴的なのは「TCP/IP の破壊」などという想定外に振り切った本音に見て取れるかと思います。こうした発言が出たあたり、非常にやった甲斐を感じました。


アーキテクチャ編は、去年より幅広いポジションの方々に出て頂き、それぞれの視点から現実的な話をして頂きました。去年の CROSS で「リアルタイム」として語っていた内容が、「ゲーム」というより具体的なものに繋がり、新しい技術の適応先の一例として興味深い話も出ました。確かに今回は出て頂いた方の携わる分野的な偏りもあったと思いますが、それでも現在の Web について語る上で、ゲームを「完全には無視できない」というのが自分としては盲点だったところかと思います。


全体を通しては、「TLS 前提の Web」という風潮の是非に対する、プロトコル編 / アーキテクチャ編双方のスタンスに割と明確な差異が見いだせました。プロトコルを考えるロール、それを用いてサービスを運用するロール、双方の意見が聞けたのがこのセッション構成をとった 1 つのメリットとして見いだせたのかなと思っています。


反省点は色々ありますが、少なくとも [twitter:muddydixon] さんに「もうやるな」と言われない限りは続けていきたいなと思っています。
(あと、 1 年に 1 回だと少し間が長いし、もっと色々な方とも議論もしてみたいので、 CROSS 以外にも場を作ったり、場が無ければ Podcast にしてみても面白いかなぁ、などと思っています。)


あまり俺が色々書くより、セッションの最後でも話した、参加者による「自分の考える次世代 Web」ブログにそこは譲って(出てくるといいなぁw)、自分のまとめとしてはここまでで。

最後に、出て頂いた登壇者の皆さん。参加して下さったみなさん。そして CROSS スタッフのみなさん。本当にありがとうございました & お疲れ様でした!

Jxck



Intro

2014/1/17(Fri) に開催される CROSS2014 にて、
CROSS2013 に引き続き「次世代 Web セッション」というセッションを担当させていただくことになりました。

今日はこのセッションの意図と概要について書こうと思います。
セッションで扱わない内容などについても言及するので、参加される方はこのエントリを README(趣意書) だと思って参加前に目を通して頂ければと思います。


去年のログ: これからの Web の話をしよう。 (次世代 Web セッション @ CROSS2013)

テーマ

このセッションのメインテーマは去年と同じです。

「次世代 Web セッション」ではいま起こっている Web の変化について、

  • 「何が起こっているのか」
  • 「どこに向かっているのか」

を議論することを目的としています。


また、その議論の主軸を絞るために 2h の枠を

の 2 つのセッションに分けて議論します。

登壇者

今年も豪華な登壇者の方々に集まって頂くことができました。
(公式サイト用プロフィールを引用)

プロトコル編」

@さん
Aria2/Spdylay/nghttp2/Wslay の作者 https://github.com/tatsuhiro-t
@ さん
Chromium Project にて、主に WebSocket, XHR の実装及び関連仕様の標準化を担当。それ以前は、現職にて Load balancer の開発、大学にて FPGA を用いた TCP/IPv6/10GbE の高速化研究など。
@ さん
2009年頃から主にIETFを中心とした標準化活動に参加。現在、通信プロトコル、認証・認可等のセキュリティ領域、プログラミング言語処理系等を主な活動対象としている。


アーキテクチャ編」

@ さん
2011年よりカヤックに入社。自社サービス、ソーシャルゲームのサーバインフラ、運用、監視を担当。
@ さん
2006年はてな入社、2010年より2代目CTO。技術的なことであれば、なんでも好物。はてなのサービスと技術の進化を加速させていきます。著書に「サーバ・インフラを支える技術」「大規模サービス技術入門」など
@ さん
ネットウォッチが高じてプログラマに。とにかくJavaScriptを高速化したい。ネイティブに負けたくない。CoffeeScript等のAltjsが好きで、最近だとLLVMEmscriptenに興味がある。

モチベーション

Web は絶えず変化しています。前回の CROSS2013 からも 1 年経って変わったところがいくつもあります。
この変化をキチンと把握し続けるのはなかなか難しいことです。

例えば「SPDY とは?」といった部分的話は割りとしやすいので、初心者向けの話は多くのイベントでされています。
(自分もよくお話させて頂いています。)

一方で、そうした初心者向けの話は、もう聞き飽きている人も多くいます。
しかし、初心者向けセッションの「その先」を扱うのは実は難しいのが現実です。


次世代 Web セッションは「その先」に挑戦したいと思っています。


「どこに向かっているのか」に答えを持っている人はいません。しかし、僕ら技術者はそこにコミットすることはできると思います。

「どこに向かっているのか」を考えるには、まず今「なにが起こっているか」をきちんと把握する事も必要です。


そこで自分は

  • 「何が起こっているのか」
  • 「どこに向かっているのか」

について、きちんと議論する場を作りたいと思い、その議論ができるであろう方々に声をかけさせて頂きました。

お断り

このセッションは、答えを出すセッションではありません。
答えが出せる、出ているような話は、わざわざここで議論する気はありません。


自分たちが「次世代の Web」を考える上で必要な知見を、常にそれを考えて戦っている方々との議論の中から見出そうというのがこのセッションの目的です。


参加するだけで答えが教えてもらえるという期待を持つ方は、このセッションには参加しないことをおすすめします。

扱わない内容

1 時間は、ちょっと真面目に議論すればあっという間に過ぎてしまう時間です。
その限られた時間の中で本来のテーマに集中するために、切り捨てる内容について書きます。

これは、自分が今回「あまり積極的に扱う必要がない」だろうと考えているものです。 といってもさじ加減なので、実際は登壇者の方々に委ねます。
しかし、参加者の方には「前提」として考えていただきたいと思っています。

初心者向け内容

例えば「SPDY とは何か?」「REST とは何か?」「IETF とは何か?」etc といった話には時間を割きません。
ある程度の知識は前提として、それを踏まえて先について話すことを重視します。
知識を得て Catch Up するためではなく、議論を通して Move Up するセッションにしたいという思いがあります。

過去の事

今回、テーマにはあえて「過去」を入れていません。 懐古するためのセッションとは考えていません。

  • 「何が起こっているのか」(現在)
  • 「どこに向かっているのか」(未来)

もちろん、古きを知ることは重要です。
過去の事例が引き合いに出ることもあると思いますが、過去を改めてから未来を語るには時間がたりません。
過去は基本的には共有された前提として考えて、「その先」にフォーカスして議論したいと考えています。

登壇者紹介

こうしたセッションで、自己紹介で大きく時間を浪費するセッションをよく見ます。
今回の登壇者のみなさんは著名な方が多く、このセッションを聞きに来る方は知っている人が多いと思います。
彼らの自己紹介に時間を割く気はありません、みなさん自己紹介を聞きに来るわけでもないでしょう。
なので、冒頭に自分がみなさんの名前を紹介する程度とさせて頂きます。


各登壇者の紹介は、このエントリや公式サイトのセッション概要から見ることもできますので。予め見ておいて頂けると良いと思います。

進め方

流れを決めすぎると予定調和になってしまうので、打ち合わせの段階でおおまかな方向性とキーワードのみを決めておき、
当日はそれについて基本的にはフリースタイルで議論を進めていきたいと思っています。


あまりズレて行くなら、途中で切るなどはしすまが、その場で起こる議論をなによりも大事にしたいです。

雰囲気については、去年の映像をご参照下さい。

まとめ

最後にもう一度。
このセッションは、 Web について

  • 「何が起こっているのか」
  • 「どこに向かっているのか」

に 1 時間フォーカスし続け、「その話はもう知ってるよ」とか、「何度も聞いたよ」みたいな話を無くして、少しでも議論の密度を高めたいです。
そのために参加者には「前提」を求める部分が多くなる点はありますが、限りある時間を有効に使うためにご理解ください。
これだけの方が揃ったセッションなので、変わりゆく Web の今後を考える上で、少しでも熱く有益な議論ができる場を作れればと考えています。


今年も去年同様、「最後は自分の頭で考えろ」(by @) で行きたいと思います。
このセッションで得たものをベースに、あなたが考える「次世代 Web」についてのエントリが読めることを、楽しみにしています。

Jxck