flow による型のある世界入門

39
Copyright © DeNA Co.,Ltd. All Rights Reserved. flow ににににににににににに にににに DeNA Games Osaka にに に に にに 西 [email protected]

Upload: sairoutine

Post on 11-Apr-2017

635 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

flow による型のある世界入門

株式会社 DeNA Games Osaka 技術部 人西 聖樹 [email protected]

Page 2: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

自己紹介

人西 聖樹(ひとにし まさき)

Twitter: @sairoutine

株式会社 DeNA Games Osaka

Web アプリケーションエンジニア

Page 3: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

今日話すこと

型とは

なぜ静的型付けが必要か

flow とは

flow と TypeScript の比較

Page 4: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

Page 5: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

「型システムとは、プログラムの各部分を、それが計算する値の種類に沿って分類することにより、プログラムがある種の振る舞いを起こさないことを保証する、計算量的に扱いやすい構文的手法である。」

Pierce, B. C. (2013) 『型システム入門 プログラミング言語と型の−理論 』住井英二郎 − ( 監訳 ), 遠藤他 ( 訳 ), オーム社 .

Page 6: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

例えば Java ( 型のある言語 ) とかだと

int a = 1; // ← ここでの int が型

static int square(int param) // ← 返り値に int 型を宣言、引数に int 型の param を宣言

{

int value; // ← ローカル変数に int 型の value を宣言。

value = param * param; return value;}

Page 7: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

静的型付けと動的型付け

静的型付け

⁃ コンパイル時に型をチェックする

⁃ 型がおかしいとそもそも実行すらできない

⁃ Java 、 C 、 C# などの言語

動的型付け

⁃ プログラム実行時にチェックする

⁃ 型がおかしくてもプログラムが実行されるまでわからない

⁃ JavaScript 、 Python 、 Ruby 、 Perl などの言語

Page 8: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

JavaScript で使われるデータ型一覧

数値

文字列

論理値

null undefined オブジェクト

Page 9: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

JavaScript は動的型付け

動的型付けなので変数にはどんな型を入れてもよい

関数の引数や返り値も柔軟に修正/変更できる 簡単! 静的型付けの言語では、変数にいれるデータの型

は決まっている 関数の引数や返り値の型を変更すると、関数の呼

び出し側も修正しなければならない 大変……

Page 10: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

JavaScript は動的型付けのメリットを選択したプログラミング言語

Page 11: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

しかし、今日では JavaScript に静的型付けの必要性が叫ばれています。

今回お話する flow も JavaScript に静的型付けを導入するツールです

Page 12: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

なぜか

Page 13: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

大規模なフロントエンド開発、開発したフロントエンドシステムの長期的保守が必要になってきた。

Page 14: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

長期的に保守されるシステム

大規模で複雑なシステム

継続的にリファクタしていくシステム

ミッションクリティカルなシステム

保守するエンジニアが入れ替わっていくシステム

→ 動的型付け言語のメリットが活かせない

Page 15: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

フロントエンドにも静的型付けが必要。ただし現状フロントエンドを実装できる言語は JavaScript の一択

Page 16: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

JavaScript に静的型付けを導入したい

Page 17: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

flow

Page 18: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

Flow

JavaScript のコードに型定義 (annotation) を追加できるようになる

By Facebook 型のチェックのみしてくれる

コンパイラというより型チェッカー

本番コードでは、 Babel 等の仕組みで型定義をコードから削除する

日本では flowtype という呼称が一般的ですが、本スライド内では flow で呼称を統一します。

Page 19: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

Google Trend

「 flowtype 」で検索 (2017/03/14 現在 )

Page 20: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

静的型付けのメリット コードがより読みやすくなる

⁃ 型定義を読むことで関数を使う際にどんな引数が必要で、どんな値が返ってくるか想像をつけることができる

⁃ 引数や返り値の型が決まっているので、予想外の値が引数や返り値に含まれることを想像しなくてよい

コードのバグを事前に発見しやすくなる⁃ 型定義の誤りはコンパイル時にわかる⁃ 運用して初めて型の誤りによるバグに気づくということが

減る IDE のサポートを受けやすくなる

⁃ エディタの補完などが便利に リファクタしやすくなる

⁃ リファクタによって、関数の引数や返り値のデータ構造を破壊してしまっても、コンパイル時に気づくことができる

Page 21: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

静的型付けが有利なシステムとは

長期間保守されることが想定されるシステム⁃ コードが後から読みやすいメリット⁃ コードは書かれる時間より読まれる時間の方が圧倒的に多い

大規模なシステム⁃ 複数人で開発する場合⁃ クラスや関数のインターフェイスを型定義により明確にできる

継続的にリファクタされるシステム⁃ リファクタによるデータ定義の破壊に気づくことができる

ミッションクリティカルなシステム⁃ 型定義の違いによるバグはコンパイル時に発見できる⁃ 型というルールを設けることでバグを減らせる

システムに関わる人が入れ替わるシステム⁃ 人が入れ替わっても型定義はコードに残る⁃ 関数の引数や戻り値を、コードを読み解いて調べなくても良い

Page 22: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

実際のコード例

Page 23: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

flow を使う準備

# babel の準備npm install -g browserifynpm install --save-dev [email protected] babel-preset-es2015# flow の準備npm install --save-dev flow-bin babel-plugin-transform-flow-strip-typesecho '{"presets": ["es2015"],"plugins": ["babel-plugin-transform-flow-strip-types"]}' > .babelrc

flow-bin がチェッカー本体で、babel-plugin-transform-flow-strip-types が、Babel によるトランスパイル時にコード上の型定義を除去してくれるプラグイン

Page 24: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

flow を使う準備

"scripts": { "flow": "$(npm bin)/flow", },

package.json に flow チェッカーを追加

[ignore].*/node_modules/.*[include]

[libs]

[options]

.flowconfig を作成して node_modules 配下を無視する設定を追加

Page 25: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

サンプルコード

// @flow

(function() { function foo(x) { return x * 10;}

foo('Hello, world!');});

文字列「 Hello, World! 」に掛け算をおこなっている、いかにも怪しいコード

// @flow を追加することで、 flow のチェック対象となる

Page 26: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

$ npm run flow

5: return x * 10; ^ string. The operand of an arithmetic operation must be a number.

特にまだ型定義は追加していないが、flow がエラーを吐いてくれる。

→ 引数に String を渡しているにも関わらず、関数内で数値として扱っているのをFlow が発見してエラーにしている。

→ flow の 型推論 機能

Page 27: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

サンプルコード

// @flow

(function() { function foo(x: string, y: number): number { return x.length * y;}

foo('Hello', 42);});

関数の引数に型定義を追加するパターン

Page 28: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

サンプルコード

// @flow

function total(numbers: Array<number>) { var result = 0; for (var i = 0; i < numbers.length; i++) { result += numbers[i]; } return result;}

total([1, 2, 3, 4]);

配列の型定義

Page 29: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

サンプルコード

// @flow

// 独自の型type Comment = { author: string; text: string;};

const comment: Comment = { author: "sai", text: "hello, world!",};

function create_text (comment : Comment) : string { return comment.author + " says " + comment.text;}

console.log(create_text(comment));

独自の型定義も可能

Page 30: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

サンプルコード

// @flow

(function() { function length(x) { return x.length;}

var total = length('Hello') + length(null);})

Null が入る場合

Page 31: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

$ npm run flow

7: return x.length; ^ property `length`. Property cannot be accessed on possibly null value7: return x.length; ^ null

Null が入る可能性があるため、エラーになる。flow は Null 安全

Page 32: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

// @flow

(function() { function length(x) { if (x !== null) { return x.length; } else { return 0; }}

var total = length('Hello') + length(null);});

Null であることをきちんとチェックすれば OK

Page 33: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

(function() { function length(x : ?string) : number { if (x != null) { return x.length; } else { return 0; }}

var total = length('Hello') + length(null);});

型推論に任せず、 Null を許容する型を定義する方法も flow にはある

Page 34: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

React や Flux, Redux との連携

容易にできるらしい

React 周りに詳しくないので詳細は別の方の資料にお任せします。

【 Electron + react + flowtype】 TweetDeck ライクなpixiv クライアント PixivDeck をつくった

http://qiita.com/akameco/items/fa80b9a325e3d1e8fd5b

Type-Safe Flux Using Flowtype https://speakerdeck.com/joere/type-safe-flux-using-fl

owtype

Page 35: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

JavaScript に静的型付けを導入するには、TypeScript を使う選択肢もある

Page 36: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

TypeScript

AltJS By Microsoft ES6 ベース 型定義を追加することができる コンパイラが型定義をチェックしてくれる JavaScript というより TypeScript という言語 WebStorm や Visual Studio Code などの IDE による

サポートがある Null 安全でない (TypeScript 2.0 から strictNullChecks

オプションで Null 安全に ) 静的型付けの恩恵を受けたい場合、 TypeScript を採用す

る手もある

Page 37: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

flow と TypeScript の比較

flow⁃ 既存の JavaScript コードにも適用できる

⁃ 一部のコードにだけ静的型付けを適用することもできる

⁃ JavaScript + 型定義なので、学習コスト低

⁃ あくまで型チェッカー。それ以上のことはしない

TypeScript⁃ 型定義以外の恩恵 ( クラス定義構文など ) が受けられる

⁃ 導入するとなると、全コードを TypeScript に置き換える覚悟

⁃ TypeScript の文法などの学習が必要

⁃ IDE のサポートが豊富 (Visual Studio Code や WebStorm など )

Page 38: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

まとめ

フロントエンド開発の大規模化、長期的な保守に伴い、静的型付けの重要性が認識されてきた

JavaScript に静的型付けを導入するには、 flow と TypeScript のおおまかに二種類が存在する。

flow は既存のシステムに追加する場合に、 TypeScript は新規のシステムに追加する場合に便利

両者とも型定義は非常に似通っている。

Null 安全についての扱いが両者は異なる

プロジェクトやチームにとって最適な選択で、静的型付けを導入しよう

Page 39: flow による型のある世界入門

Copyright © DeNA Co.,Ltd. All Rights Reserved.

ご清聴ありがとうございました