Slide 1

Slide 1 text

Be, Don't Do 存在論的プログラミング 時間と存在を記述する Akihito Koriyama (@koriym) 1

Slide 2

Slide 2 text

パラダイム 物の見方・考え方の枠組み 2

Slide 3

Slide 3 text

プログラミングパラダイム史 50s アセンブラ:マシンの言葉で考える LDA #$01 ; Aレジスタに1をロード(6502) CLC ; キャリーフラグをクリア ADC #$02 ; 2を加算 STA $00 ; メモリに保存(1+2=3) 60s 手続き型:手順で考えられるようになった for ($i = 0; $i < count($data); $i++) { process($data[$i]); } 70s- オブジェクト指向:モノとして考えられるようになった $user->validate(); $user->save(); 3

Slide 4

Slide 4 text

世界認知の拡張 50s アセンブラ:マシンの認知 60s 手続き型:世界を手順で認知 70s- オブジェクト指向:世界をモノとして認知 LDA #$01 ; Aレジスタに1をロード(6502) CLC ; キャリーフラグをクリア ADC #$02 ; 2を加算 STA $00 ; メモリに保存(1+2=3) for ($i = 0; $i < count($data); $i++) { process($data[$i]); } $user->validate(); $user->save(); 4

Slide 5

Slide 5 text

第1層:亀裂 見慣れたコードの、奇妙さ $user = new User('Alice'); $user->delete(); // $user ? echo $user->getName(); // "Alice" ? null ? exception ? 5

Slide 6

Slide 6 text

第1層:亀裂 User クラスのメソッド interface User { public function register();    // すべてが、常に利用できる public function verifyEmail(); public function login(); public function logout(); public function updateProfile(); public function changePassword(); public function addAddress(); public function removeAddress(); public function addPaymentMethod(); public function removePaymentMethod(); public function addToCart(); public function removeFromCart(); public function addToWishlist(); public function removeFromWishlist(); public function checkout(); public function trackOrder(); public function cancelOrder(); public function requestRefund(); public function writeReview(); 6

Slide 7

Slide 7 text

第2層:WHETHER? 問いの転換 HOW? どうやるか(手続き型) WHAT? それは何か(オブジェクト指向) WHETHER? そもそも存在できるか(Be) 7

Slide 8

Slide 8 text

第2層:WHETHER? それは存在可能か 年齢がマイナスの人はいない 生まれる前に死ぬことはできない 8

Slide 9

Slide 9 text

第3層:見え始めるもの $email と書いたのに public function register(string $email) { if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { throw new Exception("Invalid email"); } // ... } 9

Slide 10

Slide 10 text

第3層:見え始めるもの 意味変数 存在するものは必然的に存在し、存在しないものは必然的に存在しない——スピノザ(1677) /** @link https://schema.org/email */ final class Email { #[Validate] public function validate(string $email): void { if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { throw new InvalidEmailException(); } } } // どのコンストラクタでも自動検証 public function __construct(string $email) {} 10

Slide 11

Slide 11 text

第3層:見え始めるもの 名前を装飾する // $ageは0-150歳 public function __construct(int $age) {} // #[Teen]で13-19歳に public function __construct(#[Teen] int $age) {} 11

Slide 12

Slide 12 text

第3層:見え始めるもの 名前が関係になる public function __construct( string $email, string $confirmEmail, // 自動で一致検証 int $min, int $max, // 自動で min < max ) {} 12

Slide 13

Slide 13 text

第3層:見え始めるもの 名前に制約が宿る 言霊——言葉に宿る霊力。名前が現実を規定する——日本 public function __construct( public string $email, // フォーマット制約 public float $bodyTemperature, // 値の範囲制約 public string $inStockItemId, // ビジネスルール制約 ) {} 13

Slide 14

Slide 14 text

第3層:見え始めるもの 万物流転 卵 → 幼虫 → さなぎ → 蝶 同じ川に二度入ることはできない——ヘラクレイトス(紀元前5世紀) 14

Slide 15

Slide 15 text

第3層:見え始めるもの $being ——運命の地図 アリストテレスはこれをデュナミス(可能態)と呼んだ——紀元前4世紀 public Success|Failure $being; public Delivered|Returned|Lost $being; 15

Slide 16

Slide 16 text

第3層:見え始めるもの $been ——存在の自己証明 あなたは私ではない。どうして私が魚の気持ちを知らないと分かるのか?——荘子(紀元前4世紀) final readonly class EmergencyCase { public BeenProcessed $been; public function __construct( #[Input] float $bodyTemperature, #[Input] int $heartRate, #[Input] Emergency $being ) { $this->been = new BeenProcessed( actor: 'triage-system', evidence: ['temp' => $bodyTemperature, 'hr' => $heartRate] ); } } 16

Slide 17

Slide 17 text

第3層:見え始めるもの 内在と超越 内在 × 超越 = 変容した内在 17

Slide 18

Slide 18 text

第3層:見え始めるもの なりたい自分になる 各クラスは「何をするか」ではなく「何であるか」を定義する エンテレケイア——内に目的を持つもの——アリストテレス(紀元前4世紀) OrderInput → ValidOrder → InStockOrder → PaidOrder → DeliveredOrder 18

Slide 19

Slide 19 text

第3層:見え始めるもの 運命は分岐する // 一本道 #[Be(ValidUser::class)] final readonly class UserInput { ... } // 分岐——$being が型で決定する #[Be([EmergencyCase::class, ObservationCase::class])] final readonly class TriageAssessment { public Emergency|Observation $being; } 19

Slide 20

Slide 20 text

第4層:回収 例:トリアージ // 意味変数検証 final class BodyTemperature { #[Validate] public function validate(float $bodyTemperature): void { if ($bodyTemperature < 30.0 || $bodyTemperature > 45.0) { throw new LethalVitalException(); // 存在できない } } } // 意味例外 #[Message([ 'en' => 'Vital signs indicate non-survivable conditions.', 'ja' => 'バイタルサインが生存不可能な状態を示しています。' ])] final class LethalVitalException extends DomainException {} 20

Slide 21

Slide 21 text

存在の起点 患者がバイタルサインとともに到着する // 入力クラス #[Be([TriageAssessment::class])] final readonly class PatientArrivalInput { public function __construct( public float $bodyTemperature, public int $heartRate ) {} } 21

Slide 22

Slide 22 text

存在の分岐 トリアージプロトコルが運命を決める // 存在クラス($being で分岐) #[Be([EmergencyCase::class, ObservationCase::class])] final readonly class TriageAssessment { public Emergency|Observation $being; public function __construct( #[Input] float $bodyTemperature, // 内在 #[Input] int $heartRate, // 内在 #[Inject] JTASProtocol $protocol // 超越 ) { $urgency = $protocol->assess($bodyTemperature, $heartRate); $this->being = ($urgency === 'emergency') ? new Emergency() : new Observation(); } } 22

Slide 23

Slide 23 text

存在が能力を決める final readonly class EmergencyCase { public string $priority; // "IMMEDIATE" public string $color; // "RED" public function __construct( #[Input] float $bodyTemperature, #[Input] int $heartRate, #[Input] Emergency $being ) { $this->priority = 'IMMEDIATE'; $this->color = 'RED'; } public function assignER(): string { ... } // この能力はここだけ } final readonly class ObservationCase { public function __construct( #[Input] float $bodyTemperature, #[Input] int $heartRate, #[Input] Observation $being ) {} public function assignWaitingArea(): string { ... } // この能力はここだけ } 23

Slide 24

Slide 24 text

主体が変わっていく 言葉は存在の家である——ハイデガー(1947) [Input] PatientArrivalInput ($bodyTemperature, $heartRate) | [Being] TriageAssessment $being | [Final] EmergencyCase ObservationCase assignER() assignWaitingArea() $been $been 24

Slide 25

Slide 25 text

複雑な世界も同じ構造 道は常に無為にして、而も為さざることなし——老子(紀元前6世紀) OrderInput ($items, $customer, $payment) | ValidationOrder $being | +--- InvalidOrder $been | +--- ValidOrder --- InventoryOrder $being | +--- OutOfStockOrder --- PendingOrder $being | | | +--- BackOrder $been | +--- CancelledOrder $been | +--- InStockOrder --- PaymentOrder $being | +--- FailedPaymentOrder $been | +--- PaidOrder --- FraudCheckOrder $being | +--- SuspiciousOrder $been | +--- ClearedOrder --- ShippingOrder $being | +--- DeliveredOrder $been +--- ReturnedOrder $been 25

Slide 26

Slide 26 text

存在の生成 生じたものはその刹那に滅する。滅することに他の因を待たない。——大毘婆沙論(2世紀) $becoming = new Becoming($injector); $final = $becoming(new OrderInput( $items, $customer, $payment )); 26

Slide 27

Slide 27 text

DX から AX へ DX: Developer Experience — 人間にとって書きやすいコード AX: AI Experience — 人間とAIの双方が理解できる構造 👤 何が存在すべきか WHETHER を定義する 🤖 どう実現するか HOW を解く 27

Slide 28

Slide 28 text

Tell, Don't Ask — Object Oriented Be, Don't Do — Being Oriented 28

Slide 29

Slide 29 text

削除も存在 $user->delete() // $user? $deleted = new DeletedUser($user) // $user? ActiveUser → DeletedUser 29

Slide 30

Slide 30 text

技術のエッセンス OOP / FP / DDD / MVC … 30

Slide 31

Slide 31 text

Doing から Being へ Doing Being 中心 動詞(どう動かすか) 名詞(何であるか) 変化 他者が変化させる 自己が変容する 時間 手順の連続 状態の変容 正しさ テストによる検証 存在していること自体が証明 開発者 実装する人 存在の条件を定義する人 31

Slide 32

Slide 32 text

異なる言葉、同じ問い 思想 概念 Being ヘラクレイトス 万物流転 Input → Being → Final アリストテレス 可能態 Success|Failure $being 老子 無為 #[Be] 宣言 スピノザ 必然的存在 意味変数 フッサール 内在における超越 #[Input] + #[Inject] 荘子 自己証明 $been ハイデガー 言葉は存在の家 クラス名=世界構築 仏教 刹那滅 不可逆な変容 32

Slide 33

Slide 33 text

"The world is a system of ever-changing relationships and structures." テッド・ネルソン——5歳の時、湖でボートから手を水に入れた体験から 33

Slide 34

Slide 34 text

#[Be(NewParadigm::class)] final class You { public readonly Vision $vision; public function __construct( #[Input] Understanding $before, // 内在 #[Inject] Insight $today, // 超越(この後いなくなる) ) { $this->vision = new Vision($before, $today); } } 34

Slide 35

Slide 35 text

$being 35