2012-03-31 闇鍋の中に投げ込むdartの矢 カンペ
TRANSCRIPT
スライド 1
東 悟大(Godai Azuma)
@godai_0519
id:godai_0519闇鍋プログラミング勉強会 2012/03/31(土)
資料URL: http://goo.gl/JAZ4t
次のセッション
Dart について
資料 URL
http://www.slideshare.net/godai_0519/2012
0331
http://goo.gl/JAZ4t
スライド 2 自己紹介
• 本名: 東 悟大
• Twitter: @godai_0519• Hatena: godai_0519
• 所属: 国立東京工業高等専門学校(いわゆる高専)情報工学科(仮)配属 1年 → 情報工学科2年
• 年齢: 16歳
• 主な言語: C++,Dart-lang,C#,Java etc2
• C++好き(というか一番まともに書ける言語かもしれない)Boostとかも使ってたり
なんの捻りもない質素なアイコン
自己紹介とかしておきます。
Twitter ではこんな質素なあいこんで(ry
スライド 3 話すこととか
• Dartってなに?
• 基本的なこと
• 特徴
• ライブラリとか– io
– dart:isolate
• dartrefjp
今日の発表はこんな感じで
スライド 4 Dartってなに?
• Googleが2011年10月10日の「GOTOカンファレ
ンス」で公開した新しいWeb系言語。
• 2012年3月31日現在、未だ開発中。(最新0.08)
• Java・JavaScriptの影響を強く受けた考え方。
• JavaScriptの解決できない言語上の問題点を解
決し、置き換えを目指す。
JavaScriptに有る解決できない言語上の問題点とは?
当初は Dashを呼ばれていた言語
スライド 5 Dartってなに?
• 現在のWebアプリケーション開発
– スクリプト言語で開発したWebアプリケーションは、
デバッグ作業が非常に難しい。
– 作者以外がコードの維持することは困難。
– サーバーサイドで同一の言語を使用できない。(Node.jsやGoogle Web Toolkitなどを除く)
– JavaScriptが性能の面で充分でない。
– 大規模開発に向いていない。
スライド 6 Dartってなに?
• 設計目標
– Webのための「構造的で柔軟」な言語
– Javaのような「馴染みやすい」言語
– 高パフォーマンスと高速な実行速度
– 携帯からタブレット、ラップトップを含む幅広い環境で実行できる言語
– 主要なブラウザ全てで実行できる言語
クロスコンパイル : Chrome, Safari 5+,
Firefox 4+
スライド 7
あれ?FirefoxやSafariが対応して
くれないと使えないんじゃね?
スライド 8 実行環境
• JavaScriptにクロスコンパイル
– dartc (Java製)
– frog (Dart製)
• Dart VM
– Dartium
• Dartboard
– 簡単なDartコードをビルド
DartC
スライド 9
なんとなく解ったところで、簡単な事項を
さらっと見て行きましょう
ス ラ イ ド
10 Hello World
• Hello Worldはトップレベルのmainから
• 実行結果
main() {print('Hello, Dart!');
}
Hello, Dart!
‘’でも””でも問題ない
スライド 11 リテラル
• nullリテラル– null
• 真偽値リテラル– true– false
• 数値リテラル– 255– 0xff– 0xFF– 25500e-2– 255.00
• リストリテラル– <int>[1, 2, 4, 8, 16]– const<int>[1, 2, 4, 8, 16]
• マップリテラル– <int>
{ "Hello" : 1,"Dart" : 2,"!!" : 3 }
– const<int>{ "Hello" : 1,"Dart" : 2,"!!" : 3 }
マップリテラルについてわかりやすく
ス ラ イ ド
12・13 リテラル
• 文字列リテラル(1)
"Hello, Dart!" // Hello, Dart!
'Hello, Dart!' // Hello, Dart!
"It's Dart!" // It's Dart!
'''複 // 複¥n数¥n行
数
行'''
'文字列¥n' //文字列¥n
@'文字列¥n' //文字列¥¥n
リテラル
• 文字列リテラル(2)
– String Interpolation(文字列補間)
• $変数名 → 変数値
• ${式} → 式の結果
main() {final int n = 256;
print('n = $n'); // n = 256print('n/8 = ${n/8}'); // n/8 = 32
}
ス ラ イ ド
14 型
じゃあどんな型があるの?• int : 整数型(...-3,-2,-1,0,1,2,3...)• double : 浮動小数点数型(3.1415926535... etc.)
• String : 文字列型("a","abcdefghi" etc.)• bool : 論理型( true , false )• List : リスト• Set : 集合• Queue : キュー
• Map : 辞書• 2
実はこれ全部、coreライブラリのインターフェースなんです。
ス ラ イ ド
15 型
• 5つのスーパーインターフェースの実装関係
Comparable 比較可能
Hashable ハッシュ可能?
Pattern 様式?
Iterable 反復可能
Map
ス ラ イ ド
16・17 関数
• 戻り値の型 関数名(引数リスト){ 処理 }– 処理内にreturnで値を返す
– return文がないとき、暗黙的にreturn null;が追加される
• 戻り値の型 関数名(引数リスト) => 式;
– 式の結果を戻り値として返す
int square(int x) {return x * x;
}
int square(int x) => x * x;
クラス
• コンストラクタでメンバを簡単に初期化
• 演算子オーバーロード可能
class Point {num x, y;Point( [ num this.x, num this.y ] ); // ctorPoint operator+(Point other)
=> new Point(this.x + other.x, this.y + other.y);}
~~~Point point1 = new Point(5, 19); // point1.x == 5, point1.y == 19Point point2 = new Point(3, 31); // point2.x == 3, point2.y == 31Point point3 = point1 + point2; // point3.x == 8, point3.y == 50
ス ラ イ ド
18 クラス
• 定数コンストラクタ
• ファクトリーコンストラクタ
class Point {final num x, y;const Point(this.x, this.y); // 定数コンストラクタfactory Point.createOrigin() => const Point(0, 0); // ファクトリーctor
}
~~~Point point1 = const Point(5, 19); // point.x == 5, point.y == 19Point point2 = new Point.createOrigin(); // point.x == 0, point.y == 0
constは本体書けません。
真偽値・数値・文字(定数リテラルの補間済
み含む)・定数リスト・定数マップリテラル
定数変数への参照・定数コンストラクタを呼
び出した変数・定数値に対する比較演算
子
ス ラ イ ド
19 静的変数
• トップレベル変数・static
• ライブラリやクラス全体に関連付け
– 特定のインスタンスだけでない
• 明示的な型指定がない →Dynamic(var)
• コンパイル時定数で初期化
• 遅延初期化
– 静的変数が読まれて初めて初期化される
トップレベルの変数は、暗黙的に静的、
static が付いているとコンパイル時エラーに
なる。
静的変数は、特定のインスタンスに関連付
けられているのではなく、ライブラリやクラス
全体に関連付けされる変数。
変数宣言は明示的に型を指定しない場
合、宣言された変数の型は、Dynamic で
す。
静的変数の宣言は、遅延初期化されま
す。静的変数が読み取られ、初めて、それ
はその初期化子の評価結果に設定され
る。静的変数はコンパイル時定数で初期化
されていない場合、現在の実装では、コン
パイル時エラーを与えます。
これで、多くの初期化の計算を行なってし
まい、一つの長いアプリケーションの起動
時間を引き起こしてしまうという問題を回避
でき、クライアントアプリケーションをコーデ
ィングするために設計された Dart のために
特に重要である
ス ラ イ ド
20
Dartの特徴
ス ラ イ ド
21 • Dartの型付けは自由!
– varを使って動的型付
– 型名を使って静的型付
これにより、
デバッグ作業が難しい問題と、
大規模開発をしにくい問題を回避!
Optional typing
var = Dynamic 型
ス ラ イ ド
22 変数宣言で型を指定するのは自由!
• 静的型付
• 動的型付
int x = 256;String str = "Hello, Dart!";
var x = 256;var str = "Hello, Dart!";
Optional typing
ス ラ イ ド
23 関数宣言で型を指定するのは自由!
• 静的型付
• 動的型付
int square(int x) => x * x;int twice(int x) => x + x;
square(x) => x * x;twice(x) => x + x;
戻り値の型も省略OK
引数の型も省略OK
String型はoperator+が定義されているのでtwiceの引数にとれます
Optional typing
twiceは数字じゃなくても…
'val1.MUL$operator' is not a function
ス ラ イ ド
24 ジェネリックスの<>も自由!
• 静的型付
• 動的型付
List prime = [2, 3, 5, 7, 11, 13, 17];Map windows = {"XP": 2001, "7": 2009};
List<int> prime = <int>[2, 3, 5, 7, 11, 13, 17];Map<String,int> windows = <int>{"XP": 2001, "7": 2009};
ジェネリックスの<>も省略OK
リテラルの<>も省略OK
<>を省略した場合、<Dynamic>を指定したことと同義
Optional typing
mapの使い方は少し複雑
new List() == new List<Dynamic>()
ダイナミックは、 "型指定されていない"変
数の背後で使用される型です。
new List() is shorthand for new
List<Dynamic>().
Dynamic is the type used behind the
scenes for “untyped” variables.
ス ラ イ ド
25 Dartの型チェック
• プロダクションモード– 型チェックはwarningを発生させるだけ
– 実行に影響の有るエラー検出 →例外発生
– 実行・パフォーマンス優先
• チェックモード– 型チェックはコンパイル時と実行時に。
– 実行に影響の有るエラー検出 →動作停止
main() {
int n = "Hello, Dart!"; // ※}
Dartにおける型システム
warningを発生させることで開発者を助
ける。≠最適化
ス ラ イ ド
26 スナップショット
• 特定の状態とコードをすべて記録・保存しておくことが出来る
• →起動の大きなスピードアップが見込める
• 54000行のWebアプリでの実行テスト
– スナップショット無しで640msで起動
– スナップショット有りで60msで起動
現在、ブラウザはそのアプリケーションが実
行する前に Web アプリケーションのソース
コードを解析する必要があります。
ダーツコードはスナップショットを、すべて
のことができ、その状態、およびコードの時
間かなりの起動をスピードアップすることが
でき、特定の時点で記録されます。
初期のテストでは、ダートコードの 54000
行を持つ Web アプリケーションがスナップ
ショットなしで 640msで起動。
スナップショットと、それは 60 ミリ秒で起
動。
あなたのダーツプログラムはダートの VM
で実行されている場合、それは重要な起動
時のパフォーマンスの改善、スナップショッ
トのおかげで見ることができます。
ス ラ イ ド
27 他の言語との違い
• トップレベルでの関数定義が「推奨」
• 名前の衝突はプレフィックスを使って回避できる
• ただし静的メンバのみのクラスも作成可能
• 初期化されていない変数はnullである保証
• クロージャに渡された変数の値は渡された時点のものをキャプチャする。
var callbacks = [];for (var i = 0; i < 2; i++) {
callbacks.add(() => print(i));}callbacks.forEach((c) => c());
JavaScript
22 Dart
01
ス ラ イ ド
28
暗黙的暗黙的暗黙的暗黙的に定義
暗黙的暗黙的暗黙的暗黙的に定義
class Container {String str;// String get str() => str;// void set str(String s) {// str = s;// }
}
class Container {Container(this.str);final String str;// String get str() => str;
}
メンバのカプセル化
フィールドにフィールドにフィールドにフィールドに直接アクセス直接アクセス直接アクセス直接アクセス
getter/setterで
アクセス区別できない
class Container {String str;// String get str() => str;// void set str(String s) {// str = s;// }
}
class Container {Container(this.str);final String str;// String get str() => str;
}
フィールドを定義すると getterと setter
が暗黙的に用意される。
フィールドに直接アクセスすることと
getter/setter を利用することは区別でき
ない。
ス ラ イ ド
29 ライブラリ
• (built-in)
• dart:core
• dart:coreimpl
• dart:isolate
• dom– JSとちょっと違うよ!
(多分)
• html
• io
• json
• uri
• utf
elem.getElementById('foo');
elem.getElementsByTagName('div');
elem.getElementsByName('foo');
elem.getElementsByClassName('foo');
elem.querySelector('.foo .bar');
elem.querySelectorAll('.foo .bar');
elem.query('#foo');
elem.queryAll('div');
elem.queryAll('[name="foo"]');
elem.queryAll('.foo');
elem.query('.foo .bar');
elem.queryAll('.foo .bar');
ス ラ イ ド
30 io
• ファイルI/O
– File
– Directory
• HTTPアクセス
– Socket
– ServerSocket
– HttpClient
– HttpServer
File ファイルの作成・削除とストリームの提
供
Directory ディレクトリの作成と削除、存在
確認・リストアップ。temporary ディレクトリの
管理とか
Socket 普通のソケット。入出力用のストリー
ムを保持
ServerSocket 通 信 が 開 始 さ れ る と 、
Socketを作成してハンドラーを呼出
HttpClient HttpClientConnectionを作成し、
HTTP通信の開始を支援
HttpServer リクエストが来たときにハンドラ
ー呼び出しを行う
ス ラ イ ド
31 よくサンプルにされる、使い古されたファイルコピー
main() {final String workingDir = newDirectory.current().path;
final File inputFile = new File("${workingDir}/input.txt");final InputStream istream = inputFile.openInputStream();
final File outputFile = new File("${workingDir}/output.txt");final OutputStream ostream = outputFile.openOutputStream();
istream.pipe(ostream);ostream.onClosed = () => istream.close();
}
io
コピー先の用意
コピー元の用意
ス ラ イ ド
32 io
• HttpServer
– listen
• 動作ホスト・ポートを指定
– onRequest
• リクエストが来たときのハンドラーを指定
– onError
• エラー発生時に呼び出されるハンドラーを指定
void listen
(String host, int port, [int backlog])
void set onRequest
(void handler(HttpRequest, HttpResponse))
void set onError
(void handler(String errorMessage))
ス ラ イ ド
33 io
• HttpClient
– ホスト名やUriからHttpClientConnectionを生成
• HttpClientConnection
– onError
– onRequest
• リクエスト送信時のハンドラーを指定
– onResponse
• レスポンスが帰ってきた時のハンドラーを指定
void set onError
(void handler(HttpException e))
void set onRequest
(void handler(HttpClientRequest request))
void set onResponse(void
handler(HttpClientResponse response))
ス ラ イ ド
34・35
void server() {HttpServer service = new HttpServer();service.listen("127.0.0.1", 8080);service.onRequest = (HttpRequest req,HttpResponse res){
StringBuffer buffer = new StringBuffer();req.inputStream.onData = () => buffer.add(new String.fromCharCodes(req.inputStream.read()));req.inputStream.onClosed = () {
print("Catched: ${buffer.toString()}");res.outputStream.writeString('Re: ${buffer.toString()}');res.outputStream.close();
};};
}
void client() {HttpClient client = new HttpClient();HttpClientConnection connection = client.open("POST", "127.0.0.1", 8080, "/");
connection.onRequest = (HttpClientRequest req) {req.outputStream.writeString("Hello, Dart!");req.outputStream.close();
}; connection.onResponse = (HttpClientResponse res) {
StringBuffer buffer = new StringBuffer();res.inputStream.onData = () => buffer.add(new String.fromCharCodes(res.inputStream.read()));res.inputStream.onClosed = () => print("Returned: ${buffer.toString()}");};
}
Catched: Hello, Dart!Returned: Re: Hello, Dart!
実行結果(server → client)
io
• ゆうとさん(@yutopp)はDartのHttpClientを
利用してこんなのを書きました。
• いかにしておっぱい画像をダウンロードするか~2012 Dart編
– http://yutopp.hateblo.jp/entry/2012/03/23/114047
– http://goo.gl/qKd7g
ス ラ イ ド
36 Isolate
• Dartのコードは全てIsolateで実行される ←ここ重要• 全てのIsolateは、シングルスレッド
– Isolateを新たに起動し、マルチスレッド化可能– 複数のIsolate間でsend/receive出来るのは単純な型
• オブジェクトの共有は行わず、有るのは通信のみ。• Isolateは未だ発展途中
– 現時点でIsolateクラスは非推奨となり、代わりとなるAPIが提供されています。
• 考え方が複雑です。 →誰かkwsk教えてください!
isolateという「英語の」意味を調べてみ
た。
孤立させる。隔離する。分離する。
ス ラ イ ド
37 Isolate
• トップレベルに ReceivePort get port();
• ReceivePort– いくつかのSendPortを持つ
– toSendPortよりSendPortを得られる
– 配信したSendPortから送信されたメッセージは登録されたコールバックに渡される
• SendPort– sendで対応したReceivePortを呼び出す
– さらにcallでは返信呼び出しの指定ができる
初期の ReceivePort はこの isolate のた
め、デフォルトで利用できるもの。
自動的に作成され、一般的に isolate 間の
最初の通信を確立させるために使われ
る。
ス ラ イ ド
38 function() {// call受け取り宣言port.receive((msg, SendPort replyTo) {
for(int i=0; i<1000; ++i) {print("${msg}: $i");
}replyTo.send("Completed ${msg}-function");
});
// ここはcallを待たずして実⾏されるコードprint("Ready!");
}
実⾏結果Ready!Ready!two: 0two: 1one: 0one: 1one: 2two: 2~~~two: 998two: 999Completed two-functionone: 341one: 342~~~one: 998one: 999Completed one-function
Isolate
main() {// 関数からSendPortを作るSendPort oneSendPort = spawnFunction(function);SendPort twoSendPort = spawnFunction(function);
// SendPortからcallし、replyはprintで受け取るoneSendPort.call("one").then(print);twoSendPort.call("two").then(print);
}
ス ラ イ ド
39 Isolate
• spawnFunction(void topLevelFunction())
– トップレベルに存在する関数からIsolateを生成する
• spawnUri(String uri)
– URIより実行可能なコードのisolateを生成する
"I so late"このネタはパブリックド メインにします・w・
使えませんでした!!(汗;
@USAGI_WRPさん
関数クロージャ使えない
ど ち ら も 、 子 の isolate の ポ ー ト を
SendPort として返す
spawn 引き起こす. 生じる. 生む.
ス ラ イ ド
40 dartrefjp
• Dartの日本語レファレンスサイト– http://sites.google.com/site/dartrefjp/
– 英語公式の情報を日本語で提供
• dartrefjp Google Group(現在14人)– Dartに関する各種日本語の情報共有や意見交換
• DartJP / facebook group(現在18人)
– 気軽に参加できるDartの日本語グループ
• 協力者求むっ!
ス ラ イ ド
41
まとめ(?)
今回のセッションを通して、皆さんにどんな
ことを伝えたかったのかというと。
ス ラ イ ド
42・43
こんな発表でも、誰かがDartに興味を
持って頂けるとしたら、
それはとっても嬉しいなって
ス ラ イ ド
44・45 参考ページなど
• Dart: Structured web apps | DartLang.org– http://www.dartlang.org/– http://news.dartlang.org/
• dartrefjp– http://sites.google.com/site/dartrefjp/
• What is Dart? - O'Reilly Media– http://shop.oreilly.com/product/0636920025887.do
• 本の虫– http://cpplover.blogspot.jp/
• InfoQ: Google Dartのエッセンス(ry– http://www.infoq.com/jp/articles/google-dart
ご清聴、ありがとうございました。
ス ラ イ ド
46
そして質疑応答