jsx generator-impl
TRANSCRIPT
2013/10/26 東京node学園祭
JSXのジェネレータ実装西脇友一 / @wasabiz
13年10月26日土曜日
自己紹介
✤ 西脇友一
✤ @wasabiz
✤ 東京大学教養学部2年 (理学部情報科学科進学予定)
✤ DeNAアルバイト
13年10月26日土曜日
DeNAでの業務
✤ プログラミング言語JSXの開発と保守
✤ 言語仕様のデザイン
✤ コンパイラの開発・バグフィックス
✤ etc
✤ 基本はコンパイラ屋さん
13年10月26日土曜日
✤ リリースされていないJSXの機能についてしゃべります
✤ 今後のリリースまでに変わる可能性が十分にあります
13年10月26日土曜日
今日のキーワード
✤ nodejs
✤ ES6
✤ ジェネレータ
✤ 非同期処理
✤ JSX
13年10月26日土曜日
node.js
✤ 近々node.js v0.12がリリースされます
✤ ECMAScript6対応 (いわゆるJavaScriptの最新規格)
✤ 目玉機能の一つがgenerator
✤ generatorでコールバック地獄からおさらばする話
13年10月26日土曜日
generatorとは
✤ 一時停止・再開ができる関数
✤ 現代的なプログラミング言語のほとんどがサポート
✤ PythonのGenerators
✤ RubyのFibers
✤ C#, Go, Lua, ...etc
✤ JavaScriptは?
13年10月26日土曜日
ECMAScript6のgenerators
✤ 1997 - ECMAScript 1
✤ 最初の規格
✤ 2008 - ECMAScript 4
✤ 破棄
✤ 2009 - ECMAScript 5 / 2011- ECMAScript 5.1
✤ 仕様の厳格化、リフレクション
✤ 広く浸透している版
✤ 2013 - ECMAScript 6
✤ 多数の新機能の追加、generatorが導入される
13年10月26日土曜日
例: ES6のジェネレータfunction * fib () { var a = 1, b = 1; while (true) { yield a; [a, b] = [b, a + b]; }}
f = fib();f.next().value; //=> 1f.next().value; //=> 1f.next().value; //=> 2f.next().value; //=> 3f.next().value; //=> 5f.next().value; //=> 8
13年10月26日土曜日
ブラウザでのサポート状況
✤ Chrome (v8)
✤ ES6準拠のgeneratorを導入
✤ そしてnode.jsも0.12からサポート
✤ Firefox
✤ ES6が登場するはるか前に独自拡張として導入(JavaScript 1.7)
✤ 他のブラウザが追従せず普及しなかった
✤ generatorはある
✤ ES6と互換性がない
✤ IE/Operaは未だサポートせず
13年10月26日土曜日
ブラウザでのサポート状況
✤ Chrome (v8)
✤ ES6準拠のgeneratorを導入
✤ そしてnode.jsも0.12からサポート
✤ Firefox
✤ ES6が登場するはるか前に独自拡張として導入(JavaScript 1.7)
✤ 他のブラウザが追従せず普及しなかった
✤ generatorはある
✤ ES6と互換性がない
✤ IE/Operaは未だサポートせず
→ 互換性の壁
13年10月26日土曜日
JSXの場合
13年10月26日土曜日
JSX
✤ ユーザーが書くコードは単一
✤ コンパイル結果をターゲットのブラウザ(JSエンジン)ごとに変える
✤ 全てのブラウザに互換性のある形の JSにコンパイル
✤ ジェネレータがあるブラウザ(Fx, Ch)
✤ → ブラウザでサポートされている形式に変換
✤ そもそもサポートしていないブラウザ
✤ → special care
13年10月26日土曜日
コード例
function fib () : Enumerable.<number> {! var a = 0, b = 1;! while (true) {! ! var t = a;! ! a = b;! ! b = t + b;! ! yield a;! }}
JSXで書かれたコード
13年10月26日土曜日
Chrome(v8)
function fib () : Enumerable.<number> {! var a = 0, b = 1;! while (true) {! ! var t = a;! ! a = b;! ! b = t + b;! ! yield a;! }}
function fib * () {! var a = 0, b = 1;! while (true) {! ! var t = a;! ! a = b;! ! b = t + b;! ! yield a;! }}
13年10月26日土曜日
Firefox
function fib () : Enumerable.<number> {! var a = 0, b = 1;! while (true) {! ! var t = a;! ! a = b;! ! b = t + b;! ! yield a;! }}
var fib = $__jsx_g_fx(function fib () {! var a = 0, b = 1;! while (true) {! ! var t = a;! ! a = b;! ! b = t + b;! ! yield a;! }});
13年10月26日土曜日
その他
function fib () : Enumerable.<number> {! var a = 0, b = 1;! while (true) {! ! var t = a;! ! a = b;! ! b = t + b;! ! yield a;! }}
function fib() {! var a;! var b;! var t;! var $START;! var $TEST_WHILE_0;! var $BODY_WHILE_0;! var $YIELD_0;! var $END_WHILE_0;! var $END;! var $generator0;! $generator0 = new __jsx_generator$x2E$x3Cnumber$x3E();! $START = (function () {! ! (a = 0, b = 1);! ! $TEST_WHILE_0();! });! $TEST_WHILE_0 = (function () {! ! if (true) {! ! ! $BODY_WHILE_0();! ! } else {! ! ! $END_WHILE_0();! ! }! });! $BODY_WHILE_0 = (function () {! ! t = a;! ! a = b;! ! b = t + b;! ! $generator0.__value = a;! ! $generator0.__next = $YIELD_0;! });! $YIELD_0 = (function () {! ! $TEST_WHILE_0();! });! $END_WHILE_0 = (function () {! ! throw new StopIteration();! ! $END();! });! $END = (function () {! });! $generator0.__next = $START;! return $generator0;}
generatorをIE/operaでも動くJSに変換して出力
13年10月26日土曜日
コード例
f = fib();
f.next(); //=> 1f.next(); //=> 1f.next(); //=> 2f.next(); //=> 3f.next(); //=> 5
どのJSエンジンでもジェネレータが動く
13年10月26日土曜日
小まとめ
✤ generatorという便利なものがあります
✤ node.js v0.12.0に入る予定
✤ ブラウザでのサポートはまちまち
✤ そもそもgeneratorが無いもの(IE/Opera)
✤ あっても互換性がないもの(Firefox)
✤ JSXは非互換な部分を吸収するレイヤー
13年10月26日土曜日
Why generators matter?
13年10月26日土曜日
Why generators matter?
✤ node.jsの問題点
✤ コールバック地獄
✤ ジェネレータでコールバック地獄は無くせる
✤ Qやcoといったサードパーティライブラリ
13年10月26日土曜日
co
var fs = require('fs');
fs.readFile('input.txt', , function(err, data) {! fs.writeFile('output.txt', data, function (err) {! ! console.log('It\'s saved!');! });});
↓
13年10月26日土曜日
co
var fs = require('fs');
fs.readFile('input.txt', , function(err, data) {! fs.writeFile('output.txt', data, function (err) {! ! console.log('It\'s saved!');! });});
var co = require('co');var fs = require('fs');
co(function *() { var data = yield thunkify(fs.readFile)('input.txt'); yield thunkify(fs.writeFile)('output.txt', data); console.log('It\'s saved!');});
↓
13年10月26日土曜日
await式
✤ 将来のECMAScriptで非同期関連の構文(await)が導入される
✤ ES7で入るとか入らないとか
✤ C#のasync/awaitに似た構文
✤ `function ! () { }`になるとか`function ^ () { }`になるとか
✤ もちろんまだ利用できない…
✤ ES5.1からES6まで2年
✤ ES7は2015年…?
13年10月26日土曜日
JSXの場合
✤ ECMAがまだなら自分たちで作ってしまえ!
13年10月26日土曜日
JSXは…
// ES6 with coco(function *() { var data = yield thunkify(fs.readFile)('input.txt'); yield thunkify(fs.writeFile)('output.txt', data); console.log('It\'s saved!');});
13年10月26日土曜日
JSXは…
// ES6 with coco(function *() { var data = yield thunkify(fs.readFile)('input.txt'); yield thunkify(fs.writeFile)('output.txt', data); console.log('It\'s saved!');});
// JSX (draft spec)// コンパイル結果はES6互換のJavaScriptfunction * () : void { var data = await fs.readFileAsync(‘input.txt’); await fs.writeFileAsync(‘output.txt’, data); console.log(‘It\’s saved!’);}
↓
13年10月26日土曜日
結論
✤ ジェネレータを使うと非同期APIがすごくすっきりする
✤ でもブラウザのサポートはまちまち
✤ 仕様策定もまだまだ先
✤ JSXは先回りして実装
✤ JavaScriptの非互換な部分を埋める
✤ Language as a Layer
✤ 独自言語を持つ強み
13年10月26日土曜日