PHPerKaigi 2020登壇資料
PHPerがこれから「型」とお付き合いしていくためにやなせ たかし
View Slide
自己紹介やなせ たかし株式会社ラクスで働いています。PHP歴1年未満Scala大好きマンギターを嗜みます。ギターと技術で何かしたい(願望)2
今日話すこと● 型システムとは何なのか● 型システムとプログラミング言語●PHPと型● 今から型システムとお付き合いを始めるには3
型システムとは何なのか4
型システムとは何なのか● 本セッションでの前提● 定義● 型システムでできること5
型システムとは何なのか● 元は型理論という分野○ コンピューターが存在する前からある○ 数学、論理学などで用いられる● ここでは、プログラミングに関することを話します6
型システムとは何なのか● プログラムのふるまいを推論するためのツール● 始めはintとfloatの違いを区別するようなもの○ 効率よく計算するため●1970年ごろからより高度な概念が研究される○ 部分型○ 再帰型○ 多相○ 高階型○ などなど7
型システムでできること● エラー検知● 構造を明らかにする● 安全性を高める● プログラムの効率性を高める8
● データ構造の不整合を検知してくれる○ しかも実行前にわかる● 特定のバグがないことを保証できる○ 静的に型検査をしている場合エラー検知9
● データ構造の不整合を許容しない○ 柔軟性を持たせるのには工夫が必要○ とはいえ、全てを汎用的な型で実装すると恩恵が受けられない● 特定のバグがないことを保証しなければならない○ 絶対に実行されないコードのエラーも検知してしまうエラー検知(裏の顔)10
構造を明らかにする● 利用側と実装を分離できる○ インターフェイスを型として扱うことで、利用する型を保証できる● ドキュメント化しやすい○ シグネチャーの型が正しいことは保証されている11
安全性を高める● 自身が抽象化した操作を保護できる○ 型検査の時点で不整合があるとエラーになる○ たとえば、配列を使っているだけではメモリ破壊を起こさない12
安全性を高める(裏の顔)● 多くの言語では、抜け道が存在する○ たとえば、メモリ操作APIがあるとか○ 低レベルAPIはそういうのがありがち● 「安全」の定義がまちまち○ 型安全?○ メモリ安全?13
プログラムの効率性を高める● 実行時に効率的なバイトコードを生成する○ 静的型付き言語をコンパイルする○ 低レベルで最適化できるので効率が良くなる○ 動的型付き言語でも、JITをで型情報を集めてコンパイルしていることも14
型システムがもたらすもの● 安全性と(実行時の)効率● ただし、柔軟性とはトレードオフになりがち15
型システムとプログラミング言語16
型システムとプログラミング言語17● 静的型付け・動的型付けとは● 静的型付き言語● 動的型付き言語● 両者を比較してみる
静的型付け・動的型付けとは型検査がいつ行われるかの違い● 静的型付けはコンパイル時に型検査が行われている● 動的型付けは実行時に型検査が行われている18
静的型付き言語の特徴● コンパイル時に型が検査されている● コンパイルされたら効率的なバイトコードになる● 型に不整合があるプログラムは実行できない● 型を書く必要がある言語もある○ 昔のJavaとか●(一部)型を書かなくてもいい言語もある○Scalaとか● 型を書くのがデメリットというわけではない19
コンパイルされたらどうなるの● コードが直接低レベルな命令に翻訳されている● 一方インタープリターはコードを解釈しながら実行型がわかっていれば、翻訳時に最適化が効く。=>何らかの原因で型検査が入ると効率が悪くなる● キャストやリフレクション20
動的型付き言語の特徴● 型検査は実行時に行われる● 型の不整合は実行時にエラーとなる(こともある)● 型を書ける言語も増えてきた○PHPも型を書けるようになってきましたね21
両者を比較してみる● 型を書くの?書かないの?● 型推論ってあるけど、動的言語と何が違うの?● 静的解析するから、静的型付き言語は不要では?● 結局どっちがいいの?22
型を書くの?書かないの?静的型付き言語● 書くし、書かないこともある動的型付き言語● 書かないが、書くこともある23
型をアノテーションへのモチベーション静的型付き言語● 自明なものは書かないでいいようにしていきたい動的型付き言語● 安全のために型を書こう24
型推論ってあるけど、動的言語と何が違うの?型推論● 静的型付き言語で、コンパイラが型を推論する● 実行時は型検査のないただの命令に翻訳されている動的型付き言語● 実行時まで型が決まっていない● 実行時に型検査をする25
横道:型推論について● 右辺の型を計算し、左辺の型を推論します●var a = hoge;だけではないdef map(ls, f) = ls match {case h::t => f(h) :: map(t, f)case Nil => Nil}● 上の疑似コードの型が決まるのが型推論のすごさ26
静的解析するから、静的型付き言語は不要では?● 静的型付き言語と比較すると恩恵は限定的● ある程度の恩恵は受けられる○ 静的解析できる範囲では型安全に実装できる○ 実行時の恩恵は受けられない=>漸進的型付け などと表現される27
結局どうなの優劣はないその場その場の有利不利はあるプロダクトのフェーズによっても変わる文化によっても変化する多分いつまでも優劣はつかないただし、超えられない壁はある(双方ともに)28
PHPと型29
PHPと型● どういう言語●PHPの型● 漸進的型付けの言語として30
PHPってどういう言語● 弱い型付けの動的型付き言語○ ここが柔軟性に聞いてくる● インタープリターで実行される○Opcacheはあるけどね● 型に関する改修が最近多いのはご存知の通り31
型システムを強化することへの期待● 型宣言が性能を上げる○JITで型宣言の情報を使う○ タイプヒンティングをすると性能が悪いのは過去の話■ すでにOpcacheで性能向上に利用されている(と言えなくもない)● 開発のしやすさの向上○ もちろん動的型付き言語のメリットはある程度犠牲になる○ プロダクトの長い成長に耐えるコードベースの基礎ができる32
PHPが型を手に入れるべきか後方互換性との兼ね合いが心配新規開発ならまだいいかも知れない言語の進化としても気になるところがある。=>進化がドラスティックなわりに、根本的な課題 arrayの扱いが難しいなど33
ケース1設定● 既存システムの開発者● 動的型付き言語として普通に開発されていた● レガシーシステムかもしれない● 開発環境はphpStorm=>型宣言よりphpDocをまず書く34
ケース1● 既存システムに型宣言を書くのは難しい○ 柔軟な運用をしている場合は特に●PHPDocなら動作を制限しない○ しかし、IDEの支援は受けることができる=>ある程度型システムの恩恵を受けられる35
ケース2設定● スクラッチ開発● 既存コードなんてない=>型宣言を積極的に使っていく36
ケース3設定● 既存システム● 型は意識していない● 型宣言されたライブラリを使うことになった=>オーバーロードする場合は注意型を明確にしたい場合はDTO用意するのも良し37
ケースバイケース38
以上39
Any Questions?40