flowtypeの実現する実行時例外のない世界

今日こんなスライドを見かけた。

djcordhose.github.io

これはtypescriptとflowtypeの違いがよく分かるすごく良いスライド。

このスライドの5ページ目に以下の1文がある。

FLOW SOUNDNESS, NO RUNTIME EXCEPTIONS AS GOAL

スライドに刺激を受けたのと、最近flowtypeを触っていたのもあって、これが何を指しているか書きたくなった。

実行環境

  • flow: 0.26.0
  • typescript: 1.18.10

Flowtypeのきほん

以下のjavasciptのプログラムをflowにかけてみる。

function foo(x) {
  return x * 10;
}
foo('Hello, world!');
$ flow
flow.js:5
  5: foo('Hello, world!');
     ^^^^^^^^^^^^^^^^^^^^ function call
  3:   return x * 10;
              ^ string. This type is incompatible with
  3:   return x * 10;
              ^^^^^^ number

関数fooは引数xに対して10を掛けた値を返却する。
引数xにはnumber型を期待しているが、実際にはstringを渡しているのでエラーが発生する。

非常に強力な型推論だ。

ちなみにtypescriptではこれはエラーにならない。
(まぁjsのシンタックス上エラーじゃないし)

$ node
> null * 10
0

typescriptにおいては以下のように引数xの型を明示的に指定することでこれを検知できる。

function foo(x: number) {
  return x * 10;
}
foo('Hello, world!');

これをOCamlで記述してみる。

let foo x = x * 10;;
# val foo : int -> int = <fun>

let foo x = x * 10;;の評価値がval foo : int -> int = <fun> である。
fooはintを受け取ってintを返す関数である、という評価がされた。
OCamlにおいてもxはint型だと推論されていて、flowtypeはOCaml製だけあって近い挙動を示す。

nullable typeを定義

関数fooに少し手を加えて関数barを定義する。

function bar(x) {
  if(x < 10) { return null; }
  return x * 10;
}

console.log(bar(1) * 10);

関数barは、引数が10以下である時にnullを返す。
これをflowtypeにかけてみる。

$ flow
flow.js:8
  8: console.log(a * 10);
                 ^ null. This type is incompatible with
  8: console.log(a * 10);
                 ^^^^^^ number

barはnullを返す可能性があるが、そのハンドリングをせずに * 10しているため、エラーとなる。
ここでは関数barはnullableなnumberを返す関数となったことになる。

ここでnullのチェックを入れると、このエラーは解消される。

function bar(x) {
  if(x < 10) { return null; }
  return x * 10;
}

const a = bar(1);
if (a) {
  console.log(a * 10);
}
$ flow
No errors!

この世界において、runtime exceptionが起きる可能性がまた1つ根絶された。
これが冒頭の NO RUNTIME EXCEPTIONS AS GOAL を端的に表した例だ。

これもOCamlで記述してみると、以下になる。

let bar x =
  if x < 10 then None
            else Some(x * 10);;
# val bar : int -> int option = <fun>

int optionOCamlの提供するOptionという型で、int型かもしくは値がない、ということを示している。
この挙動を知っていれば、先ほどの結果にも素直に頷ける。

スライドにも出てくるけど、typescriptも2.0でNon-nullable typeに対応するらしい。期待。
https://github.com/Microsoft/TypeScript/pull/7140

もうマージはされていて、最新repositoryで strictNullCheckstarget es6 を有効にすれば動くらしい。
今度試してみよう。

西日暮里.rbでGraphQL on RubyというLTをした

nishinipporirb.doorkeeper.jp

西日暮里.rbでGraphQLのスキーマ定義をRubyでやって、動かしてみたというLTをしてきた。
発表資料はこちら

speakerdeck.com

動かせるサンプルコードはこちらにあるので、興味がある方はお試しください。

github.com

GraphQLは特定のストレージやFWに対応する実装ではないので、何のORMを使ってどのDBにつなぐかは関係しない。
今回は使い慣れているので、ActiveRecordを使った。

今回の発表ではGraphQLをRubyに理解させられるぞ以上のことは何もできていないのが残念。
次回までにGraphQLで何か作っておきたい。

あと西日暮里.rbのオーガナイザに前回から加わらせてもらっています。
微力ながらコミュニティ運営にお力添えしていきたいと思っていますので、今後ともよろしくお願いします。

ng-sake#2 で Cafe Pitch の紹介とAngular2のComponentについてのLTをさせてもらいました

ng-sake.connpass.com

今週あった ng-sake#2 でLTさせてもらいました。

Cafe PitchはElectron + Angular2を使って最近作っているプレゼンテーションツールです。

github.com

発表資料はこちら

speakerdeck.com

資料に書いてある通りだけど、普通にReactでコンポーネント指向に慣れていればAngular2においてコンポーネントを作る際にも同じ感覚で作れる。

加えてAngular2のコンポーネント間通信には様々な方法があるので、それぞれ良き場面で取捨選択すると良さそう。

例は公式に用意してあるので、参考にすると良い。

Component Interaction - ts

慣れないうちはとりあえず@output、@inputが使えるようになればどうにかなる。

後半はディスカッション形式で、エキサイトし過ぎてめっちゃ飲んだ。

終わった後にも飲みに行って終電を逃し、最終的に同じ方面の @Quramy さんとタクシーで一緒に帰宅しつつ、タクシー代を借りるという失態を犯した。

まとめるとめっちゃ楽しくて、かつガチ勢がひしめき合っている割にはフレンドリーでいいコミュニティだなーと思いました。

是非また参加したい!