SlideShare a Scribd company logo
第1回 型の重要性
TypeScript & 関数型講座
静的型付けと動的型付けの違い
動的型付けとは
変数や、サブルーチンの引数や返り値などの値について、その型を、コンパイル時な
ど、そのプログラムの実行よりも前にあらかじめ決めるということをせず、実行時の実
際の値による、という型システムの性質(wiki)
つまり、コンパイル(トランスパイル)を行わず、直でインタプリタが解析する
● JavaScript
● Ruby
● Python
静的型付けとは
静的型付けとは、変数や、サブルーチンの引数や返り値などの値について、その型
が、コンパイル時など、そのプログラムの実行よりも前にあらかじめ決められている、と
いう型システムの性質(wiki)
コンパイル(トランスパイル)を行う。コンパイル後の形式は様々。
● Java(中間言語)
● TypeScript(JavaScript)
● C(マシン語)
静的型付けのメリット
検出できるもの
● 変数、関数等のスペルミス
● 存在しないメソッドの呼び出し
● 間違った引数でのメソッド呼び出し
● etc…
検出タイミング(早い <-> 遅い)
● コーディング時にエディタが発生させる警告
● コンパイル時のエラー
● 自動テストの失敗
● 手動テスト
● ユーザーからの苦情
プログラム実行前にバグやエラー箇所を検出できる
実行時に気付くでしょ!......本当に?
● 実行時エラーは気付きにくい
○ テストカバレッジは 100% ですか?
○ 毎回全てのパターンを手動でテストしますか?
● 実行時エラーに気を使いながらプログラミングする必要がある
○ 生産性が低くなりがち(特に大規模なリファクタリング時)
実行する前に間違いに気付ける!確実に気付ける!そう......静的型付けならね!
● 変数、関数等のスペルミス
● 存在しないメソッドの呼び出し
● 間違った引数でのメソッド呼び出し
上記に気を使わず、エラーの発生をコーディング時に前倒しするだけでも生産性は向
上する
面倒な部分はコンパイラにまかれせば良い!
でもいちいち型を書くのは面倒では?
書くのは一瞬、開発は一生
システムは市場の影響を受け、常に変化するもの。変化についていけなかったシステ
ムには死あるのみ。
書くためのコストを下げるより、変更するためのコストを下げた方が生産性が何倍にも
なる(はず)
コンパイル時の型チェックと
契約プログラミングでの型アサーションの違い
契約プログラミングとは
プログラムコードの中にプログラムが満たすべき仕様についての記述を盛り込む事で、
設計の安全性を高める技法。(wiki)
この技法を使用する事で、異常な値でのメソッド呼び出し等(つまりプログラミングミス)を
プログラム実行時に検出することができる。
function isNumber(a): boolean {
return Object.prototype.toString.call(a).slice(8, -1) === 'Number'
}
function addAmount(amountA, amountB) {
// Number でない場合、ここで弾く
if (!(isNumber(amountA) && isNumber(amountB))) throw new Error()
// amount は 0 以上というドメインルールが存在するため、ここで弾く
if (amountA < 0 || amountB < 0) throw new Error();
// ここから先、amount は 0 以上とみなせる
return amountA + amountB;
}
契約プログラミングのメリット
● プログラムが持つ暗黙的な条件をコードに落とし込むことができる
● 異常な値でのメソッド呼び出し等(つまりプログラミングミス)をプログラム実行時
に検出することができる。
契約プログラミングでの型アサーションがあれば、静的型付けはいらないのか?
否!
アサーションでプログラミングミスが検出できるのは、あくまで実行された場合のみ
型アサーションのみでは、想定しない型が引数として入って来ないことは証明できない
一方、静的型付けの場合、想定しない型が引数として入って来ないことを(ほぼ)証明できる
(null…...ゆるすまじ...)
型を活用するメリット
表現力豊かな型はプログラムを分かりやすくする
class MailAddress {
private readonly __nominal: void
constructor(public readonly value: string) {
assert(isString(value), `文字列ではありません `)
assert(5 <= value.length, `メールアドレスは 5 文字以上としてください `)
assert(value.length <= 20, `メールアドレスは 20 文字以下としてください `)
const reg = /^[A-Za-z0-9]{1}[A-Za-z0-9_.-]*@{1}[A-Za-z0-9_.-]{1,}.[A-Za-z0-9]{1,}$/
assert(reg.test(value), `不正なフォーマットです `)
}
}
MailAddress クラスの値は、5 文字以上、20 文字以下のメールアドレスとして適当な文字
列であるということがわかる。string では文字列ということしかわからない
型は制約を増やすごとに表現力が増していく
型駆動開発ができる
型駆動開発とは、まず型シグネイチャーで概略を記述し、その後で値を埋め込むプログラミングのスタイル
def main(value: Int): ClassC = {
val a = methodA(value)
val b = methodB(a)
methodC(b)
}
def methodA(value: Int): ClassA = ???
def methodB(value: ClassA): ClassB = ???
def methodC(value: ClassB): ClassC = ???
複雑な処理を型のデータフローとして整理できる
1. 期待する入力値、出力値の型を定義する
2. 出力値を算出するために必要なメソッドを実装する
○ これを「メソッドA」とすると、処理全体の流れは以下のようになる
■ 入力値 => ???(何かしらの処理) => メソッドA => 出力値
3. メソッドA の引数を対象に、2. を行う
○ これを「メソッドB」とすると、処理全体の流れは以下のようになる
■ 入力値 => ??? => メドッドB => メソッドA => 出力値
4. 2, 3 を繰り返し、最終的な入力値=> 出力値 のパイプラインを完成させる
このようにすることで、複雑な処理を整理し、矛盾のないデータフローを構築することができる
複雑な処理を型のデータフローとして整理できる 実体験
Map[ClassA, Tree[(ClassB, Map[ClassC, Tree[(ClassD, ClassE)]])]] => ??? => ClassF
ClassF を構築するために、ClassD, ClassE のタプルのツリー構造と ClassC のマップと
ClassB のタプルのツリー構造と ClassA のマップが必要だった。
シグネイチャーレベルで矛盾のないデータフローを構築できたおかげでなんとか導出でき
た。
型がなかったら絶対に破綻していた。。。
function map<T, U>(array: T[], f: (item: T) => U): U[] {
// ...
}
シグネイチャーからメソッドの内容を推測できる
表現力豊かな型システムを関数に適用すると、その関数の型シグネイチャーを見るだけ
で、その関数について知る必要のあることのほとんどを知ることができる。
型の情報は実装と差異のないドキュメントである
ドキュメントがコードと解離していくのは世の常・・・
一方、型として表現された情報は絶対に実装と解離することはない。

More Related Content

PDF
夏だからJava再入門
PDF
リーン・スタートアップについて
PDF
スクラムについて
PDF
TypeScript & 関数型講座 第3回 関数型入門
PDF
TypeScript & 関数型講座 第2回 TypeScript という言語
PDF
2024 Trend Updates: What Really Works In SEO & Content Marketing
PDF
Storytelling For The Web: Integrate Storytelling in your Design Process
PDF
Artificial Intelligence, Data and Competition – SCHREPEL – June 2024 OECD dis...
夏だからJava再入門
リーン・スタートアップについて
スクラムについて
TypeScript & 関数型講座 第3回 関数型入門
TypeScript & 関数型講座 第2回 TypeScript という言語
2024 Trend Updates: What Really Works In SEO & Content Marketing
Storytelling For The Web: Integrate Storytelling in your Design Process
Artificial Intelligence, Data and Competition – SCHREPEL – June 2024 OECD dis...
Ad

TypeScript & 関数型講座 第1回 型の重要性