1 of 52

型と型安全と、時々、型推論

2 of 52

型と型安全と、時々、型推論

はじまるよ〜〜〜〜〜!!!!

3 of 52

自己紹介

  • canalun (@i_am_canalun)
  • テックタッチという会社

4 of 52

趣味でやっていること

  • DOMDOMタイムス�(zennで週刊連載)
  • TAPL.ts�(TAPLの輪読会)
  • chromium contribution

5 of 52

本当に話したかったこと

TypeScriptの型推論の仕組みを

ちょっと見てみる

6 of 52

準備中の様子……

うんうん……

TaPLとか

7 of 52

準備中の様子……

ん??

TaPLとか

8 of 52

準備中の様子……

そもそも型ってなんだ?

TaPLとか

9 of 52

準備中の様子……

型ってなんだ

10 of 52

準備中の様子……

型ってなんだ

11 of 52

準備中の様子……

型ってなんだ?

12 of 52

準備中の様子……

型ってなんだ?

型ってなんだ?

13 of 52

準備中の様子……

型ってなんだ?

型ってなんだ?

そもそも論から始めて、

型推論はほんの少しだけにします👶

型推論の話は入れられませんでした😭

14 of 52

もっと、そもそも……

そもそも

プログラミング言語

ってなんなのさ

15 of 52

プログラミング言語を作ってみる(とする)

どんなふうに書くことができて、

どんなふうに動くか

を考える必要がある

16 of 52

要するに、2つの要素を考える

どんなふうに書くことができて、

どんなふうに動くか

いわゆる文法: Syntax

いわゆる評価方法: Semantics

(インタプリタはこれに従うってワケ)

17 of 52

syntaxとsemanticsが言語を規定する

ECMAScriptの例

ECMAScript specifications

18 of 52

syntaxとsemanticsが言語を規定する

C言語の例

ISO/IEC 9899:TC3 Committee Draft — Septermber 7, 2007; https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf

19 of 52

👶「syntaxに則っていれば動くんだね!」

20 of 52

syntaxに則っていればいいのか?その1

JavaScriptの例

文法は問題ないが、�nullへのプロパティ�アクセスをしている

👉動かない、エラーでとまる

21 of 52

syntaxに則っていればいいのか?その2

C言語の例

文法は問題ないが、�インデックスが

オーバーしている

👉動くけど、変なことが起きる

22 of 52

syntaxに則っていたらいいわけではない

  • nullのプロパティにアクセスしてた
  • 除算演算子に文字列を渡してた
  • 未定義変数にアクセスしてた
  • (ちょっと違うけど)メモリを解放し忘れてた
  • 配列の範囲外インデックスにアクセスしてた

23 of 52

なぜsyntaxに則っているだけ

ではだめなのか

24 of 52

syntaxは文脈から切り離されている……

ECMAScript specifications

25 of 52

syntaxは文脈から切り離されている……

ISO/IEC 9899:TC3 Committee Draft — Septermber 7, 2007

ECMAScript specifications

26 of 52

syntaxは文脈から切り離されている……

ISO/IEC 9899:TC3 Committee Draft — Septermber 7, 2007

ECMAScript specifications

Haskell 2010 Language Report�https://www.haskell.org/onlinereport/haskell2010/

27 of 52

syntaxは文脈から切り離されている……

ISO/IEC 9899:TC3 Committee Draft — Septermber 7, 2007

ECMAScript specifications

Haskell 2010 Language Report�https://www.haskell.org/onlinereport/haskell2010/

直前までの情報は

文法で考慮されていない

28 of 52

syntaxは文脈から切り離されている……

ISO/IEC 9899:TC3 Committee Draft — Septermber 7, 2007

ECMAScript specifications

Haskell 2010 Language Report�https://www.haskell.org/onlinereport/haskell2010/

直前までの情報は

文法で考慮されていない

やってはじめて、直前までの情報が

コンピューターの状態として顕現して

文法がその状態のもとで評価される

29 of 52

syntaxは文脈から切り離されている……

ISO/IEC 9899:TC3 Committee Draft — Septermber 7, 2007

ECMAScript specifications

Haskell 2010 Language Report�https://www.haskell.org/onlinereport/haskell2010/

直前までの情報は

文法で考慮されていない

やってはじめて、直前までの情報が

コンピューターの状態として顕現して

文法がその状態のもとで評価される

syntaxに沿っていても

プログラムがうまく動くかは

やってみるまでわからない

30 of 52

👶「やってみるまでわからない?本当に?」

31 of 52

何が起きるんだったっけ

  • nullのプロパティにアクセスしてた
  • 除算演算子に文字列を渡してた
  • 未定義変数にアクセスしてた
  • (ちょっと違うけど)メモリを解放し忘れてた
  • 配列の範囲外インデックスにアクセスしてた

などなど……

32 of 52

何が起きるんだったっけ

  • nullのプロパティにアクセスしてた
  • 除算演算子に文字列を渡してた
  • 未定義変数にアクセスしてた
  • (ちょっと違うけど)メモリを解放し忘れてた
  • 配列の範囲外インデックスにアクセスしてた

などなど……

事前にわかる(=静的解析ができる)

ものもありそう……

33 of 52

どうできるだろうか??

  • nullプロパティアクセス
  • 除算演算子への文字列渡し
  • 未定義変数アクセス
  • メモリ解放わすれ
  • 配列の範囲外アクセス

nullが来ないことを確認

数字のみが来ることを確認

変数の定義状態を確認

変数の使用状況を確認

配列の範囲を確認

34 of 52

どうできるだろうか??

  • nullプロパティアクセス
  • 除算演算子への文字列渡し
  • 未定義変数アクセス
  • メモリ解放わすれ
  • 配列の範囲外アクセス

nullが来ないことを確認

数字のみが来ることを確認

変数の定義状態を確認

変数の使用状況を確認

配列の範囲を確認

Rustはこれ

35 of 52

データの種類に関する話があるな?

  • nullプロパティアクセス
  • 除算演算子への文字列渡し
  • 未定義変数アクセス
  • メモリ解放わすれ
  • 配列の範囲外アクセス

nullが来ないことを確認

数字のみが来ることを確認

変数の定義状態を確認

変数の使用状況を確認

配列の範囲を確認

36 of 52

データの種類ならなんとかなるのでは?

bにはnullが入っている

という文脈のもとで

下の部分を解析(≠評価)して、だめだよって言えばいいのでは?

37 of 52

データの種類ならなんとかなるのでは?

bにはnullが入っている

という文脈のもとで

下の部分を解析(≠評価)したらいいのでは?

要するに

データの種類という「文脈」を考慮し

プログラムの正しさを解析してみる

38 of 52

理論上、道は少なくとも2つある

  • データの種類という文脈を含んだsyntaxの構築
  • データの種類という文脈を使った、syntaxともsematicsともすこし違う、プログラムの静的解析

39 of 52

理論上、道は少なくとも2つある

  • データの種類という文脈を含んだsyntaxの構築 👉 文脈依存文法
  • データの種類という文脈を使った、syntaxともsematicsともすこし違う、プログラムの静的解析 👉 型検査へ

40 of 52

文脈依存文法?

  • 前までの情報を考慮する文法定義の仕方
    • パースしつつ、変数の情報などを蓄積していく
  • いろいろなやり方がある
  • ALGOL 68は「属性文法」で文法を定義している
    • 佐々政孝の「属性文法」という論文が、属性文法のイメージをつかみやすい

https://www.jstage.jst.go.jp/article/jssst/3/4/3_4_377/_pdf/-char/en

41 of 52

属性文法

https://www.jstage.jst.go.jp/article/jssst/3/4/3_4_377/_pdf/-char/en

42 of 52

文脈依存文法?

  • 前までの情報を考慮する文法定義の仕方
    • パースしつつ、変数の情報などを蓄積していく
  • いろいろなやり方がある
  • ALGOL 68は「属性文法」で文法を定義している
    • 佐々政孝の「属性文法」という論文が、属性文法のイメージをつかみやすい

https://www.jstage.jst.go.jp/article/jssst/3/4/3_4_377/_pdf/-char/en

実装がすごく難しいらしい

(やったわけではないので知らない)

43 of 52

文脈依存文法?

  • 前までの情報を考慮する文法定義の仕方
    • パースしつつ、変数の情報などを蓄積していく
  • いろいろなやり方がある
  • ALGOL 68は「属性文法」で文法を定義している
    • 佐々政孝の「属性文法」という論文が、属性文法のイメージをつかみやすい

https://www.jstage.jst.go.jp/article/jssst/3/4/3_4_377/_pdf/-char/en

だったら分けよう

「データの種類」という文脈を使った検査を

文法からも評価からもわけてやろう

44 of 52

型検査とは、つまりこういうことだね

  • データの種類という文脈を使って、実行せずに、�プログラムの正しさを確認できる=安全かわかる
  • データの種類を型と呼んでみる
    • 型はいまやもっと豊かな概念だけど、ここではデータの種類であると割り切ってみる
  • 型に関する決まりは、文脈依存文法でないなら、syntaxともsematicsとも単純に言い切れなさそうで面白い

45 of 52

型検査とは、つまりこういうことだね

  • データの種類という文脈を使って、実行せずに、�プログラムの正しさを確認できる=安全かわかる
  • データの種類を型と呼んでみる
    • 型はいまやもっと豊かな概念だけど、ここではデータの種類であると割り切ってみる
  • 型に関する決まりは、文脈依存文法でないなら、syntaxともsematicsとも単純に言い切れなさそうで面白い

なんだこれ!?

46 of 52

型検査をすれば

プログラムが安全かどうか

やるまえにわかるぞ!

47 of 52

型検査をすれば

プログラムが安全かどうか

やるまえにわかるぞ!

うまく動くとか

安全とかってなに!?

48 of 52

安全という言葉は多義的で、文脈による

  • プログラミング言語の未定義動作が起こらない
  • プログラミング言語が定義している実行時エラーが起こらない
  • プログラマが意図していない挙動を起こさない
  • メモリリークなどを起こさない

49 of 52

いわゆる「型安全性」はここまで

  • プログラミング言語の未定義動作が起こらない
  • プログラミング言語が定義している実行時エラーが起こらない

  • プログラマが意図していない挙動を起こさない
  • メモリリークなどを起こさない

話し手によりさまざま

(本当の本当にオリジナルの定義はたぶん、未定義かどうかが主だと思う)

50 of 52

型安全性は個々の型検査に関する性質だね

  • プログラミング言語の未定義動作が起こらない
  • プログラミング言語が定義している実行時エラーが起こらない

👉(通常はあまりないけど)同じ言語でも型検査のやり方が異なれば、厳密には型安全性は変わってくる

51 of 52

型安全性は個々の型検査に関する性質だね

  • プログラミング言語の未定義動作が起こらない
  • プログラミング言語が定義している実行時エラーが起こらない

👉でもまあ型検査のやり方含めて言語の仕様だと思うのが普通だよね

👉だから「XXっていう言語は型安全」って言える

52 of 52

まとめ

  • 文脈を考慮した「正しさ」がある
  • その中に「データの種類」という観点がある
  • syntaxとして担保するのはけっこうたいへん
  • だから、独立させた静的検査を考える
  • 型、型検査とはそういうこと
  • 型安全性とは、型検査についての、それを通せば未定義動作がないことが保証できる性質