Download - オブジェクト指向の皮をかぶった関数型プログラミング言語 Haxe
terurou
2013/08/25
近況
• 意識の高い無職です
• 11月頃に法人を立ち上げるらしいです
• 仕事ください & 社員が1人欲しい
コミュニティ活動
• DSTokai : 東海地方のメタコミュニティ
– IT系イベントカレンダー(東海地方限定)
–コミュニティ連絡用ML
– http://go.dstokai.info/
• NGK : なごや ごうどう こんしんかい
–主に忘年会を開催
–今年は12/7(土)12/14(土)に開催予定
– 150人規模ぐらいの会場を探してるところ
• 吹上ホールの会議室になりそうな雰囲気
技術領域
• 経歴上はフロントエンドエンジニアぽい
– HTML5, WPF/Silverlight, WinRT
• アーキテクチャ設計とかもできます
• Haxe/JavaScript歴 1年強
– 20-30人規模(最大時)のSaaSプロジェクトにHaxe導入~基盤構築までやったことあります http://www.slideshare.net/terurou/haxe-15006171
関数型言語、よくわかりません
タイトルはきょんくんのせいです
話すこと
• Haxeとは
• Haxeの良いところ、悪いところ
• Haxeの特徴的な言語仕様
• まとめ
Haxeとは
• マルチプラットフォーム
• ActionScript 3由来の保守的な構文
• OCaml由来の型システム
• 3.0が最近(2013年5月)リリースされた
–言語仕様と標準ライブラリが大きく改善
マルチプラットフォーム
• 様々な環境向けに出力可能
• 特にWebフロントエンドに強い
– Flash(直接swfを出力可能)
– JavaScript(Haxe 3.0からAPIが大幅強化)
–その他にC++, Java, C#, PHPなど
• OpenFL
–次ページで解説
OpenFL(旧称 NME)
• Flash APIをマルチプラットフォーム化
– Web: HTML5, Flash
– Desktop: Windows, Mac, Linux
– Mobile: Android, iOS, Blackberry
• ゲーム, Flashアプリの移植にどうぞ
• http://www.openfl.org/
ActionScript 3由来の保守的な構文
• 基本構文はほぼActionScript 3そのもの
– C#やJavaなどにも似ている
–構文が多少冗長だがエディタでカバーできる
• 大多数の人間に馴染みの深い構文なので、学習コスト・実戦投入コストが低い
– F#とかより心理的障壁が小さい
OCaml由来の型システム
• オブジェクト指向 + 関数型
• 静的型付け + 動的型付け
–基本的には静的型付けでコードを記述する
–動的型付けはJavaScriptなどの動的な環境と相互運用を図るために用意されている
• 型安全な(信頼性の高い)コードを簡潔に
–詳細は後述
Haxeの良いところ
• 型安全
• コンパイル言語だがコンパイルが爆速
• 言語として十分にこなれている
–わりと長い開発歴(2005年~)
–わりと多いユーザー数
• エディタ環境がまとも
–コンパイラ自体がコード補完サービスを提供
Haxeの悪いところ
• 公式ドキュメント(wiki)に難がある
–リファレンスのトピックが整理されてない
–日本語訳ページは情報が古い場合がある
• 日本国内のユーザがそれほど多くない
–わりとコアなユーザはついている
–最近になって情報が増えてきた感じはする
Haxeの特徴的な言語仕様
• 型推論
• 匿名型
• 構造的部分型
• 代数的データ型 : enum
• パターンマッチング : switch式
• 抽象型 : abstract
• macro
フツーの構文の説明が欲しい人向け
• FIRST STEP to Haxe/JavaScript
–ちょっと前に書いた入門向け資料
– http://www.slideshare.net/terurou/first-step-to-haxejavascript
解説に入る前の予備知識
• Haxeでは関数ブロックが1行だけの場合はreturnを省略できる
• 以後のサンプルコードで多用してます
function add(a : Int, b: Int) { return a + b; }
function add(a : Int, b: Int) a + b;
型推論
• 「変数や関数の仮引数の型」を明示的に宣言しなくてもコンパイラが自動判定
–コードの記述量を減らすことができる
–型推論に失敗したら型エラーが出る
リファレンス
– http://haxe.org/ref/type_infer
–日本語翻訳は情報が古いので注意
型推論の例(1)
• 変数の型推論
var foo : Int = 100;
var foo = 100;
型推論の例(2)
• 型パラメータの型推論 var array = new Array<String>();
var array = new Array(); array.push("hoge"); //Array<String>になる
型推論の例(3)
• 仮引数の型推論
• 値型(Int, Float等)の推論が失敗しやすい
• 仮引数への入力補完も効かなくなるので私はあまり多用していない
function circle(r : Float) r * r * 3.14;
function circle(r) r * r * 3.14;
仮引数がうまく型推論できない例
• Float -> Float -> Floatが推論失敗
• 宣言順序によって推論失敗
function add(a, b) a + b; add(10.5, 3.1); //Float should be Int
function f(x) { /* ... */ } f(100); //ここで引数の型がIntになる f(5.5); //NG
function f(x) { /* ... */ } f(5.5); //ここで引数の型がFloatになる f(100); //OK
匿名型
• いわゆる構造体
• カスケードも可能
• リファレンス
– http://haxe.org/manual/struct
typedef Object = { id : Int, ?name : String, //省略可能な項目 }
typedef Rectangle = {>Object, size : { width : Int, height : Int }, position : { x : Int, y : Int }, }
構造的部分型
• duck-typingを静的な型として扱う
–メソッド, フィールドなどを型として宣言
–コンパイル時にシグネチャ誤りを検出できる
• Javaとかのinterfaceより気軽に使える
–クラスの継承関係は関係なく、シグネチャがマッチしているだけで良い
• リファレンス(ちゃんと解説されてない…)
– http://haxe.org/manual/struct?lang=en#structural-subtyping
構造的部分型の例
• getDate()さえ存在すればOKな例 function printTime(x : {getTime : Void -> Float}) { trace(x.getTime()); } var date = Date.now(); var obj = { getTime : function () return 0.0; }; printTime(date); printTime(obj);
代数的データ型 : enum
• 複雑な状態遷移やデータ構造を単一の型で表現できる
–後述のパターンマッチングと合わせて使うと型安全なコードを簡潔に記述できる
• C言語のenumやunionを大幅強化したもの
– enum : 定数値の集合
– union : 単一の変数に異なる型の値を設定
• リファレンス
– http://haxe.org/ref/enums
代数的データ型の例(1)
• 簡単な例 enum Color { Red; Green; Blue; Rgb(r : Int, g : Int, b : Int); } var color1 = Color.Red; var color2 = Color.Rgb(255, 127, 127); var color3 = Green; //enumの識別子を省略
代数的データ型の例(2)
• 木構造と型パラメータ enum Tree<T> { Node(children : Array<Tree<T>>); Leaf(value : T); } var tree = Node([ Leaf("leaf-1"), Node([ Leaf("leaf-2"), Leaf("leaf-3"), ]) ]);
パターンマッチング : switch式
• 複雑な条件分岐を簡潔かつ安全に記述可能
–条件分岐の誤り(存在しえない条件や重複)を検出してコンパイルエラーにする
• データとロジックの分離が容易になる
– OOPではカプセル化が基本なので分離が面倒
• リファレンス
– http://haxe.org/manual/pattern_matching
パターンマッチングの例(1)
• 代数的データ型のパターンマッチング enum Color { Red; Green; Blue; Rgb(r : Int, g : Int, b : Int); } var code = switch (color) { case Red: "#FF0000"; case Green: "#00FF00"; case Blue: "#0000FF"; case Rgb(r, g, b): "#" + StringTools.hex(r, 2) + StringTools.hex(g, 2) + StringTools.hex(b, 2); }
代数的データ型+パターンマッチがない言語では
• こういうやつが面倒
• ユーザ側にdraw()は隠したい
– package privateにする?
–別途ValueObjectを用意する?
– Contextにdraw()を移動する?
• Shapeを引数にするとダウンキャストが必要…
interface Shape { void draw(Context context); } class Rectangle implements { /* size, position */ } class Line implements { /* startXY, endXY */ }
パターンマッチングの例(2)
• enumとswitchでVisitorパターン enum Tree<T> { Node(children : Array<Tree<T>>); Leaf(value : T); } function visit(tree) { switch (tree) { case Node(children): trace("Node"); for (x in children) visit(x); case Leaf(value): trace("Leaf : " + value); } }
パターンマッチングの例(3)
• 配列のパターンマッチング
–配列の長さは固定で指定する
// _ はワイルドカードパターン switch (x) { case []: trace("空配列"); case [_, 0]: trace("要素が2つで末尾は0"); case [_, _]: trace("要素が2つ"); case _: trace("それ以外"); }
パターンマッチングの例(4)
• オブジェクトのパターンマッチング
• クラスインスタンスに対しては制限あり
–フィールドのみ(プロパティとメソッドは×)
–親クラスのフィールドも×
var mascot = { name: "ドアラ", age: 19 }; switch (mascot) { case { name: "つば九朗" }: trace("エロつばめ"); case { name: x }: //フィールド値をキャプチャ trace(x); }
パターンマッチングの例(5)
• ORパターン
switch (value) { case 0 | 1: trace("0 or 1"); case 2 | 3 | 4: trace("2 or 3 or 4"); case _: trace("その他"); }
パターンマッチングの例(6)
• ガード
–パターンにif条件を追加できる
var mascot = { name: "ドアラ", age: 19 }; switch (mascot) { case { age: x } if (x == 19): trace("つば九朗と同期のマスコット"); case _: trace("その他大勢のマスコット"); }
抽象型 : abstract
• 型をラップするためのもの – Javaなどの抽象クラスとは全く別の概念
• 暗黙の型変換と演算子オーバーロードを定義をすることが主な用途
• リファレンス
– http://haxe.org/manual/abstracts
macro
• コンパイル時にコードをAST変換する
–やる気になれば構文拡張もできる
–実際にmacroでMaybeモナド構文を実装したライブラリも存在する(Monax)
• 関数を書くのと同じ感覚で使える
• リファレンス
– http://haxe.org/manual/macros
Haxeとは
• マルチプラットフォーム
–特にWebフロントエンドとゲームに強い
• 大多数の人間に馴染みやすい構文
• OCaml由来の強力な型システム
–オブジェクト指向 + 関数型
–型安全なコードを簡潔に
最後に伝えたいこと
• JavaScript界隈の人間はHaxe触るべし
• 代数的データ型+パターンマッチングが 非常に強力
–これがない言語はやりたくなくなる
– TypeScriptにはこれがないんだよね…
• Javaが書ける人間ならHaxeを書ける
–下手にJavaScript覚えるよりも幸せっぽい
– Haxe特有のものを使わなくても恩恵は大きい