From f60b6abb1994aae0abaeb516067821f78d1e322b Mon Sep 17 00:00:00 2001 From: Akihito Koriyama Date: Thu, 19 Mar 2026 18:00:03 +0900 Subject: [PATCH 01/16] Refactor chapter 4 (Final Objects) ja/en MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove Entelechy references (3 occurrences) - Unify terminology: 内在的性質→内在, 超越的力→超越 - Remove FailedOrder code example, mention in prose - Remove duplicate sections (特徴, 変容の完成) - Add "内側からの完全性" section with Zhuangzi resonance - Reframe $been as completion evidence, not self-proof - Fix code example: direct property access instead of ->being - Add design decisions to _design/manual-style.md --- _design/manual-style.md | 112 ++++++++++++++++++++++++ manuals/1.0/en/04-final-objects.md | 122 +++++++------------------- manuals/1.0/ja/04-final-objects.md | 134 ++++++++--------------------- 3 files changed, 176 insertions(+), 192 deletions(-) create mode 100644 _design/manual-style.md diff --git a/_design/manual-style.md b/_design/manual-style.md new file mode 100644 index 0000000..51dc275 --- /dev/null +++ b/_design/manual-style.md @@ -0,0 +1,112 @@ +# マニュアル設計ドキュメント + +## ページごとの設計判断 + +### 1. 概要 (01-overview) + +**冒頭の引用を絞る**: 「なりたい自分になる (Becoming the self you want to be)」のフレームワーク説明文を削除し、プルーストの引用だけを残した。引用は一つで十分。フレームワークの説明は本文で行う。 + +**読者への語りかけを抑える**: 「って何?と思いましたか?」「実はこの疑問が〜新しい世界への入り口です」のような呼びかけを削除。読者を導こうとするのではなく、コードで見せて自分で気づかせる。 + +**コード例の具体化**: `new UserInput($_POST)` → `new UserInput($name, $email)`。`$_POST`はPHPのグローバル変数であり、Be Frameworkの哲学(明示的な入力)に反する。変数名`$rawData`も`$userInput`に変更し、型の意図を名前で示す。 + +**東洋哲学ラベルの除去**: 見出し「なぜ「コントローラー」ではないのか? (Wu Wei / 無為自然)」から`(Wu Wei / 無為自然)`を削除。本文中の「東洋哲学の「無為自然 (Wu Wei)」の思想を取り入れた」も削除。概念は庭師のメタファーで十分伝わる。ラベルを貼ると権威付けに見える。 + +### 2. 入力クラス (02-input-classes) + +**用語の簡潔化**: 「内在的性質、イマナンス(Immanence)」→「**内在(Immanence)**」。初出で一度だけ英語を併記し、以降は日本語のみ。コードコメントも`// 内在的` → `// 内在`。 + +**クラス名の改善**: `UserProfile` → `ValidatedUser`。Be Frameworkでは「何になったか」がクラス名に現れるべき。`UserProfile`は状態を示していない。 + +**「ユースケースの起点」を追加**: 入力クラスの重要な設計原則として「すべてのユースケースは固有の入力クラスを持つ」を明記。 + +**readonlyの説明を簡潔に**: 「すべてのデータは不変であり、変異ではなく変容する固定されたアイデンティティを表します」→「すべてのプロパティは `readonly` です。入力クラスの値は変更されません」。哲学用語で説明するより、コードの事実を述べる。 + +**「イマナンスの役割」セクションの削除**: 入力クラスにはトランセンデンスがない、という説明は次章(存在クラス)の内容の先取り。各章は自分の責務だけを語るべき。次章への橋渡しは末尾の一文で十分。 + +### 3. 存在クラス (03-being-classes) + +**「変わる瞬間」→「変容した存在」**: 存在クラスは瞬間ではなく結果の存在を表す。 + +**構成の整理**: 番号付きリスト(1. 誕生 2. 生 3. なりたい自分になる)を###見出しに変更。リストは手順を暗示するが、これらは段階ではなく存在の側面。 + +**料理メタファーの削除**: 「まるで料理のようです」→ 削除。パン・ワイン・花の3例に置き換え。料理メタファーは「変容」より「加工」を連想させる。 + +**メタファーの厳選**: パン(イーストは消費される)、ワイン(酵母は消費される)、花(土と水と光は花に残らない)。3例とも「超越が消える」パターンに正確に合致する。「学びは教師との出会いを通じて知恵になる」は削除—教師は消えないのでパターンに合わない。 + +**エンテレケイアの削除**: アリストテレスの概念解説を削除し、「なりたい自分になる」という見出しに凝縮。概念を名前で説明するより、構造で体験させる。 + +**人生の例の削除**: 「本を読むのは〜楽器を練習するのは〜」は説教的。コードと自然の例だけで十分。 + +**OrderValidation(橋渡し)セクションの削除**: 分岐パターンは別章(型駆動変容)の内容。 + +**老子への明示的言及の削除**: 末尾「これは冒頭の老子の教えと同じです」を削除。「自然な流れ」セクションが暗黙に呼応する。 + +**「自然な流れ」に無為の帰結を追加**: 「この流れを指揮するものはいません。各オブジェクトはただ次の存在に渡されるだけです」を追加。老子の無為(冒頭)→ 指揮するものはいない(末尾)→ 5章の自己組織化パイプラインへの伏線、という三段構造。3章では直観として植え付け、5章で仕組みとして展開する。 + +### 4. 最終オブジェクト (04-final-objects) + +**エンテレケイアの削除**: 3章で削除した概念。4章でも3箇所すべて削除。概念を名前で説明するより、構造で体験させる(3章と同じ原則)。 + +**用語統一**: 「内在的性質(イマナンス)」→「内在」、「超越的力(トランセンデンス)」→「超越」。コードコメントも `// 内在` `// 超越` に統一。2-3章と同じルール。 + +**冒頭と末尾の重複排除**: 「終着点」(旧)と「変容の完成」がほぼ同じ内容だった。「変容の完成」セクションを削除。末尾は荘子と暗黙に呼応する一文に置き換え:「最終オブジェクトは、自分が完了したことを自分で知っています。外からの問いかけではなく、内側からの確かさとして」。 + +**ユーザー視点の導入**: 冒頭「終着点」を「ユーザーにとって見えるのは、入力と最終オブジェクトだけです」から始める。InputからFinalへの関心を最初に明示。 + +**FailedOrderコード例の削除**: 成功も失敗も同じ構造であることを一文で言及。コード例は`SuccessfulOrder`のみで十分。 + +**$beenは完了の証跡(パラダイム)**: 本質的な値はpublicプロパティにあり、`$been`はいつ・誰が・何を根拠に完了したかの証跡。「テスト不要」という断定は削除。代わりに「外部から大がかりなテストを組み立てるより、内側に証拠を残すほうが簡単で実効的で統一的」というパラダイムとして提示。すべての最終オブジェクトが同じ構造で証拠を持つ統一性こそが価値。 + +**「最終オブジェクトの特徴」セクションの統合**: 3つの特徴(完全性、ユーザー価値、豊かな状態)をコード例直後の散文に統合。独立セクションとしての重複を排除。 + +**荘子との構造的呼応**: 荘子の問い「外部から観察しても内面は知れない」↔ 末尾「内側からの確かさとして」。明示的に「荘子が言ったように」とは書かない(3章の老子と同じ原則)。 + +--- + +# 文体・構成の原則 + +## 一度だけ、最も効果的な形で言う + +同じ概念を散文・箇条書き・メタファーで繰り返さない。コードのコメントが語っていることを本文で重複させない。 + +## コードに語らせる + +コードが示していることを散文で再説明しない。読者の知性を信頼する。`// 内在` `// 超越` のコメントがあれば、箇条書きで「内在的要因とは〜」と書く必要はない。 + +## メタファーは哲学的に正確に + +比喩が概念の本質を正しく反映しているか検証する。 + +- 良い例: パン(イーストは消費される)、ワイン(酵母は消費される)、花(土と水と光は花に残らない)→ 超越が消えるパターンに合致 +- 悪い例: 「学びは教師との出会いを通じて知恵になる」→ 教師は消えない。パターンに合わない + +## 具体と抽象を交互に + +概念定義 → コード → 哲学的考察 → コード → 考察のように、具体と抽象を織り交ぜる。抽象が連続すると説教になり、具体が連続するとリファレンスになる。 + +## 冒頭と末尾を共鳴させる + +冒頭の引用や問いかけは、末尾で明示的に回収しない。読者が自分で接続を発見できるよう、構造で暗示する。 + +例: 老子「道常無為而無不為」→ 末尾「自然な流れ」セクションが暗黙に呼応する。「これは冒頭の老子の教えと同じです」とは書かない。 + +## 削ることで重みを生む + +残ったものの一つ一つが重みを持つようにする。「幼少期の友人のように」のような詩的表現は、周囲のノイズが消えることで際立つ。 + +## 日本語見出しに英語注釈を付けない + +「誕生 (Birth)」ではなく「誕生」。日本語で意味が通る見出しに英語の補足は不要。英語版は別に存在する。ただしフレームワーク固有の用語(LDD等)でコード上の概念名として英語が必要な場合は例外。 + +## 用語の一貫性 + +- 「内在的性質(イマナンス)」のような冗長な二重表記をしない +- 初出で「**内在(Immanence)**」と定義し、以降は「内在」のみ +- コードコメントも「内在」「超越」で統一 + +## 日英の対応 + +- 例の数・順序・構成を一致させる +- 直訳ではなく、それぞれの言語で自然に読める表現にする +- 構造(見出し、コードブロック、セクション順)は厳密に一致させる diff --git a/manuals/1.0/en/04-final-objects.md b/manuals/1.0/en/04-final-objects.md index be99818..39f9561 100644 --- a/manuals/1.0/en/04-final-objects.md +++ b/manuals/1.0/en/04-final-objects.md @@ -13,33 +13,10 @@ permalink: /manuals/1.0/en/04-final-objects.html ## The Destination -Final Objects are the destination of the journey of metamorphosis. -They are the complete and final existence where the value users seek and the result the application wants to deliver are embodied. +For users, only Input and Final Objects are visible. The journey that began with an Input Class arrives as a Final Object—this is the destination of metamorphosis. -This is the final form achieved after the Immanence that started from the Input Class met various Transcendence and underwent natural metamorphosis. It embodies the Entelechy spoken of by Aristotle—the state where potentiality is completely actualized. +## Basic Structure -## Characteristics of Final Objects - -**Completeness (Entelechy)**: A completely actualized existence that requires no further metamorphosis. - -**Realization of User Value**: Expresses what the user truly needs, meaningful data, or the successful result of an operation. - -**Rich State**: In contrast to Input Classes, Final Objects completely express the richness of the domain. - -## Completeness of Temporal Being - -Here is an interesting question. What if there was an object so complete that it didn't need tests? - -In Be Framework, we capture the temporal existence of objects on two axes: - -- **`#[Be]`**: The self you want to become, the destination (Direction towards the future) -- **`$been`**: The self that has completed (Self-proof of past perfect) - -In traditional programming, we verify whether an object has been processed correctly with external tests. But what if the object itself contained the proof of completion? Instead of external verification, immanent self-proof becomes possible. - -## Examples - -### Result with Immanent Self-Proof ```php final readonly class SuccessfulOrder { @@ -47,20 +24,19 @@ final readonly class SuccessfulOrder public string $confirmationCode; public DateTimeImmutable $timestamp; public string $message; - public BeenProcessed $been; // Self-proof - + public BeenProcessed $been; // Evidence of completion + public function __construct( #[Input] Money $total, // Immanence #[Input] CreditCard $card, // Immanence #[Inject] OrderIdGenerator $generator, // Transcendence #[Inject] Receipt $receipt // Transcendence ) { - $this->orderId = $generator->generate(); // New Immanence - $this->confirmationCode = $receipt->generate($total); // New Immanence - $this->timestamp = new DateTimeImmutable(); // New Immanence - $this->message = "Order Confirmed: {$this->orderId}"; // New Immanence - - // Self-proof of completion + $this->orderId = $generator->generate(); + $this->confirmationCode = $receipt->generate($total); + $this->timestamp = new DateTimeImmutable(); + $this->message = "Order Confirmed: {$this->orderId}"; + $this->been = new BeenProcessed( actor: $card->getHolderName(), timestamp: $this->timestamp, @@ -74,88 +50,48 @@ final readonly class SuccessfulOrder } ``` -This object does not need external tests. This is because the `$been` property contains complete evidence of completion. +In contrast to Input Classes, Final Objects fully express the richness of the domain. Immanence has met Transcendence, undergone transformation, and reached a complete state that requires no further change. Success and failure share the same structure. A `FailedOrder` also has a `$been`—`BeenRejected`. -### Self-Proof of Error State -```php -final readonly class FailedOrder -{ - public string $errorCode; - public string $message; - public DateTimeImmutable $timestamp; - public BeenRejected $been; // Self-proof of failure - - public function __construct( - #[Input] array $errors, // Immanence - #[Inject] Logger $logger, // Transcendence - #[Inject] ErrorCodeGenerator $generator // Transcendence - ) { - $this->errorCode = $generator->generate(); - $this->message = "Order Failed: " . implode(', ', $errors); - $this->timestamp = new DateTimeImmutable(); - - // Self-proof of failure - $this->been = new BeenRejected( - reason: 'validation_failed', - timestamp: $this->timestamp, - evidence: [ - 'error_count' => count($errors), - 'error_types' => array_keys($errors), - 'error_code' => $this->errorCode - ] - ); - - $logger->logOrderFailure($this->errorCode, $errors); // Side effect - } -} -``` +## Completeness of Temporal Being -Both success and failure have self-proof of completion. Instead of external tests, the object itself holds a complete record of what happened. +In Be Framework, we capture the temporal existence of objects on two axes: -## Final Objects vs Input Classes +- **`#[Be]`**: The self you want to become, the destination (Direction towards the future) +- **`$been`**: The self that has completed (Evidence of past perfect) + +Essential values like `$orderId` and `$confirmationCode` are public properties. `$been` is different—it records the evidence of completion: who, when, and on what basis the process completed. + +## Completeness from Within + +In traditional programming, external tests judge whether an object has been processed correctly. But a Final Object holds what it is as its own structure. What was input, what happened, and what it became—all contained within a single existence, serving as evidence of completion. + +## Comparison with Input Classes | Input Class | Final Object | |-----------|-----------------| -| Pure Identity | Rich Transformed State | | Starting Point of Metamorphosis | Destination of Metamorphosis | | What User Provides | What User Receives | -| Simple Structure | Completely Realized Function | +| Simple Structure | Rich and Complete State | ## Multiple Final Destinies Objects can have multiple possible final forms determined by their nature: ```php -// From Being property of OrderValidation: -public SuccessfulOrder|FailedOrder $being; - -// Usage: $order = $becoming(new OrderInput($items, $card)); -if ($order->being instanceof SuccessfulOrder) { - echo $order->being->confirmationCode; +if ($order instanceof SuccessfulOrder) { + echo $order->confirmationCode; } else { - echo $order->being->message; // Error message + echo $order->message; // Error message } ``` -## A Completed Journey - -The path from Input to Final Object represents a complete journey of metamorphosis: - -1. **Input Class**: Pure Identity ("This is me") -2. **Being Class**: Stage of Metamorphosis ("This is how I change") -3. **Final Object**: Complete Result ("This is what I have become") - -Users are primarily interested in Input (what they provide) and Final Object (what they receive). The Being Class in between is our responsibility as designers. To bridge the gap between intention and result, it is important to understand the temporal metamorphosis of the domain well and design the mechanism of that metamorphosis. - -## Completion of Metamorphosis - -The Final Object expresses the state of Entelechy (Full Realization). It is a completely realized existence that no longer needs metamorphosis. +## The Designer's Work -It is the completed form reached after the Immanence started from the Input Class met various Transcendence and underwent natural metamorphosis. Here, there is no longer any effort to "try to become" or intention to "try to change". Everything is complete, and the value the user truly sought is realized here. This is the essential value of our system. +Designing the mechanism of transformation between Input and Final Object—that is the designer's responsibility. Users touch only the two ends, but the Being Classes in between form the backbone of the system. -This is exactly the destination of programming that Be Framework aims for—an existence that embodies "What It Is" rather than "What To Do". +The Final Object knows that it is complete, from within. --- diff --git a/manuals/1.0/ja/04-final-objects.md b/manuals/1.0/ja/04-final-objects.md index a1617fe..5fcb745 100644 --- a/manuals/1.0/ja/04-final-objects.md +++ b/manuals/1.0/ja/04-final-objects.md @@ -8,38 +8,15 @@ permalink: /manuals/1.0/ja/04-final-objects.html # 最終オブジェクト > 「あなたは私ではない。どうして私が魚の気持ちを知らないと分かるのか?」 -> +> > —「あなたは魚ではない。どうして魚の気持ちが分かるのか」と問われた時に荘子が返した言葉 (『荘子』紀元前4世紀) ## 終着点 -最終オブジェクトは変容の旅路の到達点です。 -ユーザーが求める価値、アプリケーションが届けたい結果が具現化された、完全で最終的な存在です。 +ユーザーにとって見えるのは、入力と最終オブジェクトだけです。入力クラスで始まった旅が、最終オブジェクトとして届く—これが変容の到達点です。 -これは入力クラスから始まった内在的性質(イマナンス)が、様々な超越的力(トランセンデンス)と出会い、自然な変容を経て達成した最終形態です。アリストテレスの言うエンテレケイア、すなわち潜在性が完全に現実化された状態を体現しています。 +## 基本構造 -## 最終オブジェクトの特徴 - -**完全性(エンテレケイア)**: これ以上の変容を必要としない、完全に現実化された存在です。 - -**ユーザー価値の実現**: ユーザーが本当に必要とするもの、意味のあるデータや操作の成功結果を表現します。 - -**豊かな状態**: 入力クラスとは対照的に、最終オブジェクトはドメインの豊富さを完全に表現した存在です。 - -## 時間的存在の完全性 - -ここで興味深い問いがあります。テストが不要になるほどの完全性を持つオブジェクトがあったらどうでしょう? - -Be Frameworkでは、オブジェクトの時間的存在を二つの軸で捉えます: - -- **`#[Be]`**: なりたい自分、向かう先(未来への方向性) -- **`$been`**: 完了した自分(過去完了の自己証明) - -従来のプログラミングでは、オブジェクトが正しく処理されたかどうかを外部のテストで検証します。しかし、オブジェクト自身が完了の証拠を内包していたらどうでしょう?外部による検証ではなく、内在的な自己証明が可能になります。 - -## 例 - -### 内在的自己証明を持つ結果 ```php final readonly class SuccessfulOrder { @@ -47,20 +24,19 @@ final readonly class SuccessfulOrder public string $confirmationCode; public DateTimeImmutable $timestamp; public string $message; - public BeenProcessed $been; // 自己証明 - + public BeenProcessed $been; // 完了の証跡 + public function __construct( - #[Input] Money $total, // 内在的性質 - #[Input] CreditCard $card, // 内在的性質 - #[Inject] OrderIdGenerator $generator, // 超越的力 - #[Inject] Receipt $receipt // 超越的力 + #[Input] Money $total, // 内在 + #[Input] CreditCard $card, // 内在 + #[Inject] OrderIdGenerator $generator, // 超越 + #[Inject] Receipt $receipt // 超越 ) { - $this->orderId = $generator->generate(); // 新しい内在的性質 - $this->confirmationCode = $receipt->generate($total); // 新しい内在的性質 - $this->timestamp = new DateTimeImmutable(); // 新しい内在的性質 - $this->message = "注文確認: {$this->orderId}"; // 新しい内在的性質 - - // 完了の自己証明 + $this->orderId = $generator->generate(); + $this->confirmationCode = $receipt->generate($total); + $this->timestamp = new DateTimeImmutable(); + $this->message = "注文確認: {$this->orderId}"; + $this->been = new BeenProcessed( actor: $card->getHolderName(), timestamp: $this->timestamp, @@ -74,88 +50,48 @@ final readonly class SuccessfulOrder } ``` -このオブジェクトは外部テストを必要としません。`$been`プロパティが完了の完全な証拠を内包しているからです。 +入力クラスとは対照的に、最終オブジェクトはドメインの豊かさを完全に表現した存在です。内在が超越と出会い、変容を経て、これ以上変わる必要のない完全な状態に達しています。成功も失敗も同じ構造です。`FailedOrder`も`BeenRejected`という`$been`を持ちます。 -### エラー状態の自己証明 -```php -final readonly class FailedOrder -{ - public string $errorCode; - public string $message; - public DateTimeImmutable $timestamp; - public BeenRejected $been; // 失敗の自己証明 - - public function __construct( - #[Input] array $errors, // 内在的性質 - #[Inject] Logger $logger, // 超越的力 - #[Inject] ErrorCodeGenerator $generator // 超越的力 - ) { - $this->errorCode = $generator->generate(); - $this->message = "注文失敗: " . implode(', ', $errors); - $this->timestamp = new DateTimeImmutable(); - - // 失敗の自己証明 - $this->been = new BeenRejected( - reason: 'validation_failed', - timestamp: $this->timestamp, - evidence: [ - 'error_count' => count($errors), - 'error_types' => array_keys($errors), - 'error_code' => $this->errorCode - ] - ); - - $logger->logOrderFailure($this->errorCode, $errors); // 副作用 - } -} -``` +## 時間的存在の完全性 -成功も失敗も、どちらも完了の自己証明を持ちます。外部テストではなく、オブジェクト自身が何が起こったかの完全な記録を保持しているのです。 +Be Frameworkでは、オブジェクトの時間的存在を二つの軸で捉えます: -## 最終オブジェクト vs 入力クラス +- **`#[Be]`**: なりたい自分、向かう先(未来への方向性) +- **`$been`**: 完了した自分(過去完了の証跡) + +`$orderId`や`$confirmationCode`といった本質的な値はpublicプロパティです。`$been`はそれとは異なり、いつ・誰が・何を根拠に完了したかという完了の証跡を記録します。 + +## 内側からの完全性 + +従来のプログラミングでは、オブジェクトが正しく処理されたかどうかを外部のテストが判定します。しかし最終オブジェクトは、自分が何であるかを自分自身の構造として持っています。何が入力され、何が起こり、何になったか—その全てが一つの存在の中に収まり、完了の証拠になっています。 + +## 入力クラスとの対比 | 入力クラス | 最終オブジェクト | |-----------|-----------------| -| 純粋なアイデンティティ | 豊かで変容した状態 | | 変容の出発点 | 変容の到達点 | | ユーザーが提供するもの | ユーザーが受け取るもの | -| シンプルな構造 | 完全に実現された機能 | +| シンプルな構造 | 豊かで完全な状態 | ## 複数の最終的運命 -オブジェクトはその性質によって決定される複数の可能な最終形態を持つことができます: +オブジェクトはその性質によって複数の最終形態を持つことができます: ```php -// OrderValidationの存在プロパティから: -public SuccessfulOrder|FailedOrder $being; - -// 使用方法: $order = $becoming(new OrderInput($items, $card)); -if ($order->being instanceof SuccessfulOrder) { - echo $order->being->confirmationCode; +if ($order instanceof SuccessfulOrder) { + echo $order->confirmationCode; } else { - echo $order->being->message; // エラーメッセージ + echo $order->message; // エラーメッセージ } ``` -## 完了した旅 - -入力から最終オブジェクトへの道のりは完全な変容の旅を表します: - -1. **入力クラス**: 純粋なアイデンティティ(「これが私です」) -2. **存在クラス**: 変容段階(「これが私の変化の仕方です」) -3. **最終オブジェクト**: 完全な結果(「これが私がなったものです」) - -ユーザーは主に入力(彼らが提供するもの)と最終オブジェクト(彼らが受け取るもの)に関心を持ちます。間にある存在クラスは私たち設計者の責任です。意図と結果の間の橋渡しをするためにドメインの時間的変容をよく理解し、その変容の仕組みを設計することが重要です。 - -## 変容の完成 - -最終オブジェクトは、エンテレケイア(完全実現)の状態を表現します。変容の必要がもうない、完全に実現された存在です。 +## 設計者の仕事 -入力クラスから始まった内在的性質(イマナンス)が、様々な超越的力(トランセンデンス)と出会いながら自然な変容を経て、ついに到達した完成形です。ここにはもう「なろうとする」努力も、「変わろうとする」意図もありません。すべてが完了し、ユーザーが本当に求めていた価値がここに実現されています。私たちのシステムの本質的な価値です。 +入力と最終オブジェクトの間にある変容の仕組みを設計すること—それが設計者の責務です。ユーザーが触れるのは両端だけですが、その間の存在クラスがシステムの骨格になります。 -これこそが、Be Frameworkが目指すプログラミングの到達点—「何をするか」ではなく「何であるか」が体現された存在です。 +最終オブジェクトは、自分が完了したことを内側から知っています。 --- From e488af3d5a951fb6d3f0ed179b4d0296d73d1c5d Mon Sep 17 00:00:00 2001 From: Akihito Koriyama Date: Thu, 19 Mar 2026 19:08:19 +0900 Subject: [PATCH 02/16] Refactor chapter 5 (Metamorphosis) and add Becoming chapter ja/en Add new "Becoming" chapter (04a) introducing $becoming mechanism with Hegel epigraph. Move all $becoming usage from Metamorphosis chapter to Becoming chapter (nested becoming, pipeline invocation). Metamorphosis chapter now focuses purely on #[Be()] declaration patterns. Remove redundant sections (Implementation Guidelines, Design Principles). Unify terminology (Immanence/Transcendence). --- _design/manual-style.md | 34 +++++ manuals/1.0/en/04-final-objects.md | 2 +- manuals/1.0/en/04a-becoming.md | 68 ++++++++++ manuals/1.0/en/05-metamorphosis-patterns.md | 142 ++------------------ manuals/1.0/ja/04-final-objects.md | 2 +- manuals/1.0/ja/04a-becoming.md | 68 ++++++++++ manuals/1.0/ja/05-metamorphosis-patterns.md | 141 ++----------------- 7 files changed, 193 insertions(+), 264 deletions(-) create mode 100644 manuals/1.0/en/04a-becoming.md create mode 100644 manuals/1.0/ja/04a-becoming.md diff --git a/_design/manual-style.md b/_design/manual-style.md index 51dc275..8081668 100644 --- a/_design/manual-style.md +++ b/_design/manual-style.md @@ -62,6 +62,40 @@ **荘子との構造的呼応**: 荘子の問い「外部から観察しても内面は知れない」↔ 末尾「内側からの確かさとして」。明示的に「荘子が言ったように」とは書かない(3章の老子と同じ原則)。 +### 5. 生成 (04a-becoming) + +**新規ページ**: 2-4章で部品(Input → Being → Final)を見せた後、「どう動かすか」を示すページ。`$becoming`の全使用例をここに集約。 + +**エピグラフ: ヘーゲル『大論理学』(1812年)**: 「存在は無へと移行し、無は存在へと移行する。この運動が生成である」。フレームワークの構造がヘーゲルの生成(Werden)を正確に実装している: + +- Input ≈ 純粋存在(Sein)— まだ何でもない未規定性。`#[Be()]`で方向だけが宣言されている +- Being ≈ 弁証法的媒介 — 内在と超越を受け取り、矛盾を解決する場所 +- Final ≈ 定有(Dasein)— 確定した存在。もう変容しない + +これは哲学的権威付けではなく、コードで起きていることの的確な記述。各オブジェクトが生まれた瞬間に次の存在へ引き継がれ消滅するプロセスは、「存在は無へと移行し、無は存在へと移行する」を文字通り実現している。 + +**刹那滅(仏教)との関係**: 各オブジェクトが一瞬だけ存在し即座に消滅する様態は仏教の刹那滅と構造的に類似する。ただし哲学として同一ではない。ヘーゲルの生成は目的論的発展(チェーンは最終オブジェクトへ向かう)、刹那滅は止滅と解脱を目指す。コードの上では両方の特徴が同時に現れるが、エピグラフにヘーゲルを置いたのはチェーンが発展する方向性を持つため。マニュアルには刹那滅への言及はしない。 + +**`$becoming`の責務分離**: 変容の章(旧5章)から`$becoming`の使用例をすべて生成の章に移動。変容の章は純粋に`#[Be()]`宣言パターンのみ、生成の章は`Becoming`の動かし方のみ。 + +**ネストした生成**: 存在クラスの中で`Becoming`を超越として注入し、内部から別の変容チェーンを起動するパターン。変容の章から移動。 + +### 6. 変容 (05-metamorphosis-patterns) + +**用語統一**: JA `内在的性質`/`外部環境` → `内在`/`超越`。EN `Intrinsic nature`/`External environment` → `Immanence`/`Transcendence`。コードコメントも統一。2-4章と同じルール。 + +**エピグラフの注釈削除**: EN版アインシュタイン引用の `*Analogy applying spacetime concepts to programming` を削除。3章の老子、4章の荘子と同じく読者に解釈を委ねる。 + +**`$being`プロパティ経由のアクセス修正**: 「自己組織化」コード例の `$finalObject->being instanceof` → `$finalObject instanceof`。4章で直接アクセスに変えたのと整合。ただし「運命の自己決定」内の `$this->being` は存在クラスの内部構造を説明しているため残す。 + +**Unixパイプ比較の簡潔化**: 「重要な進化」箇条書きと「自己組織化の実現」セクションを統合。2つあったコードブロックを1つに。箇条書きは散文に。 + +**「実装上の選択指針」セクションの削除**: 線形・条件分岐・ネストの各パターンはすでに上のセクション(「不可逆的時間の流れ」「運命の自己決定」「ネストした変容」)で示されている。「選択指針」という見出し自体が、設計者が恣意的にパターンを選ぶ前提に立っており、ドメインの性質が変容の形を決めるというフレームワークの思想に反する。 + +**「設計原則」セクションの削除**: 「強制しない」「シンプルに」は変容の形がドメインによって決まるなら当然の帰結であり、わざわざ原則として掲げる必要がない。「オブジェクトは自らが自らの変容を規定します」も本文全体が示していること。末尾はヘラクレイトスの段落だけで閉じる。 + +**末尾の洗練**: ヘラクレイトスとの呼応を凝縮。「川が流れるのではなく、流れそのものが川」→ ドメインは時間的存在、という構造を明確化。冒頭(アインシュタイン:時間とドメインは分割できない)から末尾(ヘラクレイトス:存在は変化そのもの)への深まりを実現。 + --- # 文体・構成の原則 diff --git a/manuals/1.0/en/04-final-objects.md b/manuals/1.0/en/04-final-objects.md index 39f9561..b3d987b 100644 --- a/manuals/1.0/en/04-final-objects.md +++ b/manuals/1.0/en/04-final-objects.md @@ -95,4 +95,4 @@ The Final Object knows that it is complete, from within. --- -There is not just one way. Learn various paths in [Metamorphosis](./05-metamorphosis.html) ➡️ +How does declared metamorphosis come to life? On to [Becoming](./04a-becoming.html) ➡️ diff --git a/manuals/1.0/en/04a-becoming.md b/manuals/1.0/en/04a-becoming.md new file mode 100644 index 0000000..aa9100e --- /dev/null +++ b/manuals/1.0/en/04a-becoming.md @@ -0,0 +1,68 @@ +--- +layout: docs-en +title: "5. Becoming" +category: Manual +permalink: /manuals/1.0/en/04a-becoming.html +--- + +# Becoming + +> "Being passes into nothing, and nothing passes into being. This movement is becoming." +> +> —G.W.F. Hegel, Science of Logic (1812) + +## Triggering Metamorphosis + +In chapters 2–4, we saw the structure of input classes, being classes, and final objects. The `#[Be()]` attribute declares "what to become," but declaration alone does nothing. `Becoming` sets that declaration in motion: + +```php +$finalObject = $becoming(new EmailInput($name, $email)); +``` + +`EmailInput` → `EmailValidation` → `UserCreation` → `WelcomeMessage`. The chain executes automatically, following each class's `#[Be()]` declaration. Each object is born, handed over to the next existence, and ceases to be. Being becomes nothing, and from that nothing the next being emerges—this movement continues until the chain reaches its end. + +## Obtaining Becoming + +`Becoming` is injected from the DI container: + +```php +final readonly class UserRegistrationPage +{ + public function __construct( + private BecomingInterface $becoming + ) {} + + public function __invoke(string $name, string $email): WelcomeMessage + { + return ($this->becoming)(new EmailInput($name, $email)); + } +} +``` + +The caller only knows what goes in and what comes out. The metamorphosis in between is determined by `#[Be()]` declarations. + +## Nested Becoming + +By using `Becoming` within a being class, one becoming can contain another: + +```php +final readonly class OrderProcessing +{ + public PaymentResult $payment; + public ShippingResult $shipping; + + public function __construct( + #[Input] Order $order, // Immanence + #[Inject] Becoming $becoming // Transcendence + ) { + $this->payment = $becoming(new PaymentInput($order->getPayment())); + $this->shipping = $becoming(new ShippingInput($order->getAddress())); + } +} +``` + +Since `Becoming` is injected as transcendence, metamorphosis chains can be triggered from within being classes as well. A diamond pattern that converges branched results into a single object is also possible. + +--- + +There is not just one way. Learn various paths in [Metamorphosis](./05-metamorphosis.html) ➡️ diff --git a/manuals/1.0/en/05-metamorphosis-patterns.md b/manuals/1.0/en/05-metamorphosis-patterns.md index e047291..903f2b5 100644 --- a/manuals/1.0/en/05-metamorphosis-patterns.md +++ b/manuals/1.0/en/05-metamorphosis-patterns.md @@ -1,6 +1,6 @@ --- layout: docs-en -title: "5. Metamorphosis" +title: "6. Metamorphosis" category: Manual permalink: /manuals/1.0/en/05-metamorphosis.html --- @@ -8,9 +8,8 @@ permalink: /manuals/1.0/en/05-metamorphosis.html # Metamorphosis > "Space and time cannot be defined independently of each other." -> -> —Albert Einstein, The Foundation of the General Theory of Relativity (1916) -> *Analogy applying spacetime concepts to programming +> +> —Albert Einstein, The Foundation of the General Theory of Relativity (1916) ## Time and Domain Are Inseparable @@ -41,20 +40,20 @@ Each moment never returns, and new existence preserves previous forms as memory ## Self-Determination of Destiny -Like living beings in reality, objects determine their own destiny through the interaction between intrinsic nature and external environment. This is not following a predetermined route, but natural metamorphosis responding to the circumstances of that moment: +Like living beings in reality, objects determine their own destiny through the interaction between immanence and transcendence. This is not following a predetermined route, but natural metamorphosis responding to the circumstances of that moment: ```php #[Be([ApprovedApplication::class, RejectedApplication::class])] final readonly class ApplicationReview { public ApprovedApplication|RejectedApplication $being; - + public function __construct( - #[Input] array $documents, // Intrinsic nature - #[Inject] ReviewService $reviewer // External environment + #[Input] array $documents, // Immanence + #[Inject] ReviewService $reviewer // Transcendence ) { $result = $reviewer->evaluate($documents); - + // Destiny is decided at this very moment $this->being = $result->isApproved() ? new ApprovedApplication($documents, $result->getScore()) @@ -63,137 +62,18 @@ final readonly class ApplicationReview } ``` - - -## Nested Metamorphosis - -Complex objects can contain their own transformation chains: - -```php -final readonly class OrderProcessing -{ - public PaymentResult $payment; - public ShippingResult $shipping; - - public function __construct( - #[Input] Order $order, // Intrinsic nature - #[Inject] Becoming $becoming // External environment - ) { - // Nested transformations - $this->payment = $becoming(new PaymentInput($order->getPayment())); - $this->shipping = $becoming(new ShippingInput($order->getAddress())); - } -} -``` - ## Self-Organizing Pipelines -The beauty of these patterns is that they're **self-organizing**. Like UNIX pipes that combine simple commands to create powerful systems, Be Framework combines typed objects to create natural transformation flows. - -### Comparison with UNIX Pipes +Like UNIX pipes that combine simple commands to create powerful systems, Be Framework combines typed objects to create natural transformation flows. ```bash # UNIX: Text flows through externally controlled pipelines cat access.log | grep "404" | awk '{print $7}' | sort | uniq -c ``` -```php -// Be Framework: Rich objects flow through intrinsically controlled pipelines -$finalObject = $becoming(new ApplicationInput($documents)); -// Objects themselves know their next transformation destination -``` - -Key evolution: -- **UNIX**: External shell controls the pipeline -- **Be Framework**: Objects declare their own destiny with `#[Be()]` - -### Self-Organization in Action - -```php -// No controllers, no orchestrators—just natural flow -$finalObject = $becoming(new ApplicationInput($documents)); - -// The object has become what it was meant to be -match (true) { - $finalObject->being instanceof ApprovedApplication => $this->sendApprovalEmail($finalObject->being), - $finalObject->being instanceof RejectedApplication => $this->sendRejectionEmail($finalObject->being), -}; -``` - -This self-organization provides: -- No external orchestration needed -- Type safety maintained -- Capabilities provided through dependency injection -- Testable independent components - -## Implementation Guidelines - -### When to Choose Linear Metamorphosis - -For sequential processing where each stage prepares the data needed for the next: - -```php -User Registration → Email Verification → Account Activation → Welcome Notification -``` - -This is suitable when failure at any stage should halt the entire process. - -### When to Choose Conditional Branching - -When the same input branches into different results based on nature or permissions: - -```php -// Implementation example: Feature differentiation by payment capability -#[Be([FullAccess::class, LimitedAccess::class, ReadOnlyAccess::class])] -final readonly class AccessDetermination -{ - public FullAccess|LimitedAccess|ReadOnlyAccess $being; - - public function __construct( - #[Input] User $user, - #[Inject] PaymentStatus $payment - ) { - $this->being = match($payment->getStatus()) { - 'premium' => new FullAccess($user, $payment->getFeatures()), - 'basic' => new LimitedAccess($user, $payment->getLimits()), - default => new ReadOnlyAccess($user) - }; - } -} -``` - -### When to Choose Nested Metamorphosis - -When executing multiple independent processes in parallel and aggregating their results: - -```php -final readonly class OrderCompletion -{ - public function __construct( - #[Input] OrderData $order, - #[Inject] Becoming $becoming - ) { - // Independent parallel processing - $this->inventory = $becoming(new InventoryCheck($order->items)); - $this->payment = $becoming(new PaymentProcess($order->payment)); - $this->shipping = $becoming(new ShippingArrange($order->address)); - } -} -``` - -## Design Principles - -Choose metamorphosis patterns according to the natural flow of domain logic: - -- **Don't Force**: Don't force into artificial patterns -- **Keep Simple**: Choose the most simple and understandable form -- **Testable**: Each metamorphosis stage can be tested independently -- **Type Safe**: Next type is guaranteed by `#[Be()]` - -Objects govern their own metamorphosis. +In UNIX, the shell controls the pipeline. In Be Framework, objects declare their own destiny with `#[Be()]`. No external control needed. No controllers, no orchestrators. -Heraclitus said "the river flows" is not correct, but rather "the flowing is the river." He believed that existence cannot be separated from change. Be Framework likewise believes that to capture essence, domain and time cannot be separated. -Domains are temporal existence. There are possibilities and being at each moment. Capturing how input classes, being classes, and final objects naturally metamorphose along the flow of time is the core of the Be Framework. +Heraclitus said "the flowing is the river." Just as it is not that a river flows, but that the flowing itself is the river, domains in the Be Framework are temporal existence that never rest until they reach their end. --- diff --git a/manuals/1.0/ja/04-final-objects.md b/manuals/1.0/ja/04-final-objects.md index 5fcb745..208f633 100644 --- a/manuals/1.0/ja/04-final-objects.md +++ b/manuals/1.0/ja/04-final-objects.md @@ -95,4 +95,4 @@ if ($order instanceof SuccessfulOrder) { --- -道は1つではありません。[変容](./05-metamorphosis.html)で様々な道を学びます ➡️ +宣言された変容はどう動き出すのか。[生成](./04a-becoming.html)へ ➡️ diff --git a/manuals/1.0/ja/04a-becoming.md b/manuals/1.0/ja/04a-becoming.md new file mode 100644 index 0000000..0d7bed7 --- /dev/null +++ b/manuals/1.0/ja/04a-becoming.md @@ -0,0 +1,68 @@ +--- +layout: docs-ja +title: "5. 生成" +category: Manual +permalink: /manuals/1.0/ja/04a-becoming.html +--- + +# 生成 + +> 「存在は無へと移行し、無は存在へと移行する。この運動が生成である」 +> +>   —G.W.F. ヘーゲル『大論理学』(1812年) + +## 変容の起動 + +2-4章で、入力クラス、存在クラス、最終オブジェクトの構造を見てきました。`#[Be()]`属性は「何になるか」を宣言しますが、宣言だけでは何も起きません。その宣言を実行に移すのが`Becoming`です: + +```php +$finalObject = $becoming(new EmailInput($name, $email)); +``` + +`EmailInput` → `EmailValidation` → `UserCreation` → `WelcomeMessage`。各クラスの`#[Be()]`宣言に従い、チェーン全体が自動的に実行されます。各オブジェクトは生まれた瞬間に次の存在へと引き継がれ、消滅します。存在が無になり、無から次の存在が生まれる——この運動がチェーンの終端まで続きます。 + +## Becomingの取得 + +`Becoming`はDIコンテナから注入されます: + +```php +final readonly class UserRegistrationPage +{ + public function __construct( + private BecomingInterface $becoming + ) {} + + public function __invoke(string $name, string $email): WelcomeMessage + { + return ($this->becoming)(new EmailInput($name, $email)); + } +} +``` + +呼び出し側が知るのは、何を入れて何が出てくるかだけです。途中の変容は`#[Be()]`宣言が決めます。 + +## ネストした生成 + +存在クラスの中で`Becoming`を使うことで、生成の中に別の生成を含むことができます: + +```php +final readonly class OrderProcessing +{ + public PaymentResult $payment; + public ShippingResult $shipping; + + public function __construct( + #[Input] Order $order, // 内在 + #[Inject] Becoming $becoming // 超越 + ) { + $this->payment = $becoming(new PaymentInput($order->getPayment())); + $this->shipping = $becoming(new ShippingInput($order->getAddress())); + } +} +``` + +`Becoming`は超越として注入されるため、存在クラスの内部からも変容チェーンを起動できます。分岐した結果を最後に1つのオブジェクトに収束させるダイアモンド型の構成も可能です。 + +--- + +道は1つではありません。[変容](./05-metamorphosis.html)で様々な道を学びます ➡️ diff --git a/manuals/1.0/ja/05-metamorphosis-patterns.md b/manuals/1.0/ja/05-metamorphosis-patterns.md index e1c02d9..cadfce0 100644 --- a/manuals/1.0/ja/05-metamorphosis-patterns.md +++ b/manuals/1.0/ja/05-metamorphosis-patterns.md @@ -1,6 +1,6 @@ --- layout: docs-ja -title: "5. 変容" +title: "6. 変容" category: Manual permalink: /manuals/1.0/ja/05-metamorphosis.html --- @@ -8,7 +8,7 @@ permalink: /manuals/1.0/ja/05-metamorphosis.html # 変容 > 「空間と時間は独立に定義できない」 -> +> >   —アルベルト・アインシュタイン『一般相対性理論の基礎』(1916年) ## 時間とドメインは分割できない @@ -40,20 +40,20 @@ final readonly class WelcomeMessage { /* ... */ } ## 運命の自己決定 -現実の生物と同様に、オブジェクトは内在的な性質と外部環境の相互作用によって、自身の運命を決定します。これは予め決められたルートを辿るのではなく、その瞬間の状況に応じた自然な変容です: +現実の生物と同様に、オブジェクトは内在と超越の相互作用によって、自身の運命を決定します。これは予め決められたルートを辿るのではなく、その瞬間の状況に応じた自然な変容です: ```php #[Be([ApprovedApplication::class, RejectedApplication::class])] final readonly class ApplicationReview { public ApprovedApplication|RejectedApplication $being; - + public function __construct( - #[Input] array $documents, // 内在的性質 - #[Inject] ReviewService $reviewer // 外部環境 + #[Input] array $documents, // 内在 + #[Inject] ReviewService $reviewer // 超越 ) { $result = $reviewer->evaluate($documents); - + // 運命は今この瞬間に決まる $this->being = $result->isApproved() ? new ApprovedApplication($documents, $result->getScore()) @@ -62,140 +62,19 @@ final readonly class ApplicationReview } ``` - -## ネストした変容 - -複雑なオブジェクトは独自の変容チェーンを含むことができます: - -```php -final readonly class OrderProcessing -{ - public PaymentResult $payment; - public ShippingResult $shipping; - - public function __construct( - #[Input] Order $order, // 内在的 - #[Inject] Becoming $becoming // 超越的 - ) { - // ネストした変容 - $this->payment = $becoming(new PaymentInput($order->getPayment())); - $this->shipping = $becoming(new ShippingInput($order->getAddress())); - } -} -``` - ## 自己組織化パイプライン -これらのパターンの美しさは、それらが**自己組織化**であることです。Unixパイプが単純なコマンドを組み合わせて強力なシステムを作るように、Beフレームワークは型付きオブジェクトを組み合わせて自然な変容の流れを作ります。 - -### Unixパイプとの比較 +Unixパイプが単純なコマンドを組み合わせて強力なシステムを作るように、Beフレームワークは型付きオブジェクトを組み合わせて自然な変容の流れを作ります。 ```bash # Unix: テキストが流れる外部制御のパイプライン cat access.log | grep "404" | awk '{print $7}' | sort | uniq -c ``` -```php -// Be Framework: リッチなオブジェクトが流れる内在的制御のパイプライン -$finalObject = $becoming(new ApplicationInput($documents)); -// オブジェクト自身が次の変容先を知っている -``` - -重要な進化: -- **Unix**: 外部のshellがパイプを制御 -- **Be Framework**: オブジェクト自身が`#[Be()]`で運命を宣言 - -### 自己組織化の実現 - -```php -// コントローラーもオーケストレーターもなし—ただ自然な流れ -$finalObject = $becoming(new ApplicationInput($documents)); - -// オブジェクトはあるべき姿になりました -match (true) { - $finalObject->being instanceof ApprovedApplication => $this->sendApprovalEmail($finalObject->being), - $finalObject->being instanceof RejectedApplication => $this->sendRejectionEmail($finalObject->being), -}; -``` - -この自己組織化により: -- 外部オーケストレーションが不要 -- 型安全性が保たれる -- 依存性注入による能力の提供 -- テスト可能な独立したコンポーネント - -## 実装上の選択指針 - -### いつ線形変容を選ぶか - -シーケンシャルな処理で、各段階が次に必要なデータを準備する場合: - -```php -ユーザー登録 → メール検証 → アカウント有効化 → ウェルカム通知 -``` - -各段階での失敗は全体を停止させる必要がある場合に適しています。 - -### いつ条件分岐を選ぶか - -同じ入力から性質や権限によって異なる結果に分岐する場合: - -```php -// 実装例:支払い能力による機能差 -#[Be([FullAccess::class, LimitedAccess::class, ReadOnlyAccess::class])] -final readonly class AccessDetermination -{ - public FullAccess|LimitedAccess|ReadOnlyAccess $being; - - public function __construct( - #[Input] User $user, - #[Inject] PaymentStatus $payment - ) { - $this->being = match($payment->getStatus()) { - 'premium' => new FullAccess($user, $payment->getFeatures()), - 'basic' => new LimitedAccess($user, $payment->getLimits()), - default => new ReadOnlyAccess($user) - }; - } -} -``` - -### いつネストした変容を選ぶか - -複数の独立した処理を並行して実行し、それぞれの結果を集約する場合: - -```php -final readonly class OrderCompletion -{ - public function __construct( - #[Input] OrderData $order, - #[Inject] Becoming $becoming - ) { - // 独立した処理を並行実行 - $this->inventory = $becoming(new InventoryCheck($order->items)); - $this->payment = $becoming(new PaymentProcess($order->payment)); - $this->shipping = $becoming(new ShippingArrange($order->address)); - } -} -``` - -## 設計原則 - -変容パターンの選択は、ドメインロジックの自然な流れに従ってください: - -- **強制しない**: 人工的なパターンに無理やり当てはめない -- **シンプルに**: 最も単純で理解しやすい形を選ぶ -- **テスト可能**: 各変容段階が独立してテストできる -- **型安全**: `#[Be()]` によって次の型が保証される - -オブジェクトは自らが自らの変容を規定します。 +Unixではshellがパイプを制御しますが、Beフレームワークではオブジェクト自身が`#[Be()]`で運命を宣言します。外部の制御は不要です。コントローラーもオーケストレーターもありません。 -ヘラクレイトスは『川が流れている』のではなく『流れているのが川だ』と言いました。存在は変化とは切り離せないと考えたのです。Be Frameworkも同じように本質を捉えるためにはドメインと時間は切り離せないものと考えました。 -ドメインは時間的存在です。その時その時の可能性と存在があります。入力クラス、存在クラス、最終オブジェクトが時間の流れに沿って自然に変容していく様を捉えることが、Beフレームワークの核心です。 +ヘラクレイトスは「流れているのが川だ」と言いました。川が流れるのではなく、流れそのものが川であるように、Beフレームワークのドメインは終端まで静止することがない時間的存在です。 --- 変数名が制約と契約をもつ[意味変数](./06-semantic-variables.html)へ ➡️ - - - From 98e35c87443efdaf237faf52c58fa3dee3a078e1 Mon Sep 17 00:00:00 2001 From: Akihito Koriyama Date: Thu, 19 Mar 2026 20:05:24 +0900 Subject: [PATCH 03/16] Refactor chapter 6 (Semantic Variables) ja/en MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Restructure around slide-derived flow: meaning → decoration → relations → constraints → failure → kotodama. Remove redundant sections (problem statement, design by contract, error handling). Show validator mechanism before usage examples. Add template support in #[Message] example naturally via code. --- manuals/1.0/en/06-semantic-variables.md | 272 +++++++++--------------- manuals/1.0/ja/06-semantic-variables.md | 270 +++++++++-------------- 2 files changed, 201 insertions(+), 341 deletions(-) diff --git a/manuals/1.0/en/06-semantic-variables.md b/manuals/1.0/en/06-semantic-variables.md index 2100c54..e952307 100644 --- a/manuals/1.0/en/06-semantic-variables.md +++ b/manuals/1.0/en/06-semantic-variables.md @@ -1,6 +1,6 @@ --- layout: docs-en -title: "6. Semantic Variables" +title: "7. Semantic Variables" category: Manual permalink: /manuals/1.0/en/06-semantic-variables.html --- @@ -9,250 +9,180 @@ permalink: /manuals/1.0/en/06-semantic-variables.html > "What exists necessarily exists, and what does not exist necessarily does not exist" > ->   —Spinoza, *Ethics*, Part I, Proposition 29 (1677) +> —Spinoza, *Ethics*, Part I, Proposition 29 (1677) -Where should data validity be guaranteed? Controller? Model? Validator? +## Meaning and Constraints -Be Framework's answer is clear: **names themselves should carry constraints**. -`$email` should not be just a string—it should be a **valid email address**. `$age` cannot have negative values. - -Semantic Variables are identifiers of information that express meaning and hold constraints—they are **complete information models**. - -## The Problem: Scattered Incompleteness - -Traditional approaches scatter the definition of meaning across multiple locations: - -```php -// Controllers/models/validators... -if (empty($name)) throw new Exception("error.name.empty"); -if (!filter_var($email, FILTER_VALIDATE_EMAIL)) throw new Exception("error.email.invalid"); - -// messages/en.yml -error.name.empty: "Name is required" -error.email.invalid: "Please enter a valid email address" - -// README.md -// "Name must be 1-100 characters, whitespace-only not allowed..." -``` - -The following problems occur: -- **Validation**: Scattered across controllers -- **Error messages**: Managed in separate files -- **Constraint rules**: Duplicated in multiple places -- **Meaning definition**: Exists only in documentation - -There is no central place to see the meanings that the system handles. - -## The Solution: Semantic Completeness - -Be Framework integrates scattered definitions into **complete information models**. Constructor arguments and class properties can only use registered **semantic variables**. - -## Defining Existence - -Semantic variables are defined as classes in dedicated folders: +`$email` is not just a string. A semantic variable is an identifier of information—it expresses meaning and carries constraints as a complete information model: ```php -final readonly class Name +final class Email { #[Validate] - public function validate(string $name): void + public function validate(string $email): void { - if (empty(trim($name))) { - throw new EmptyNameException(); + if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { + throw new InvalidEmailException(); } } } + +// Automatically applied to any constructor argument named $email +public function __construct(string $email) {} ``` -## Validation Contexts +Define it once, and it automatically applies to every constructor parameter named `$email`. The value in `$email` is not correct by accident—it is correct by necessity. What cannot be correct simply cannot exist. + +## Decorating Names -Different business contexts may require different rules. Semantic variables naturally support multiple validation contexts: +Adding attributes to the same name refines the conditions for existence. When a `#[Validate]` method has an attribute on its parameter, it only executes when the constructor argument has a matching attribute: ```php -final readonly class ProductCode +// Basic $age constraint (0–150 years) +final readonly class Age { #[Validate] - public function validate(string $code): void - { - // Standard product code validation (e.g., 8-digit alphanumeric) - if (!preg_match('/^[A-Z0-9]{8}$/', $code)) { - throw new InvalidProductCodeException(); - } - } - - #[Validate] - public function validateLegacy(#[Legacy] string $code): void - { - // Relaxed validation for legacy systems (e.g., 6-10 digit alphanumeric) - if (!preg_match('/^[A-Z0-9]{6,10}$/', $code)) { - throw new InvalidLegacyProductCodeException(); + public function validate(int $age): void + { + if ($age < 0 || $age > 150) { + throw new InvalidAgeException(); } } + // Only executed when #[Teen] attribute is present #[Validate] - public function validatePremium(#[Premium] string $code): void - { - // Strict validation for premium products (e.g., specific prefix required) - if (!preg_match('/^PREM[A-Z0-9]{4}$/', $code)) { - throw new InvalidPremiumProductCodeException(); + public function validateTeen(#[Teen] int $age): void + { + if ($age < 13 || $age > 19) { + throw new InvalidTeenAgeException(); } } } ``` -## The Meaning of Failure - -When existence fails, the meaning of failure must be preserved: - ```php -#[Message([ - 'en' => 'Name cannot be empty.', - 'ja' => '名前は空にできません。' -])] -final readonly class EmptyNameException extends DomainException {} -``` +// Only basic Age validation applied +public function __construct(int $age) {} -The framework collects not just the first thrown exception but **all validation errors** as a collection of exceptions, creating complete understanding of why existence is impossible. - -## Natural Integration - -Semantic variables work automatically in constructors: - -```php -final readonly class UserProfile -{ - public function __construct( - #[Input] #[English] public string $name, // Auto-validated as English name - #[Input] string $emailAddress, // Auto-validated as email address - #[Inject] NameFormatter $formatter - ) { - // At this point, all inputs are guaranteed valid - } -} +// Both Age + Teen validation applied +public function __construct(#[Teen] int $age) {} ``` -The variable name `$name` is automatically associated with the `Name` semantic variable class, and `$emailAddress` with the `EmailAddress` semantic variable class. +The same `$age` gets different existential conditions depending on its attributes. -## Hierarchical Validation +## Names as Relations -Semantic variables can build upon other semantic variables. This is a powerful technique for expressing the natural hierarchical structure of business rules in the type system. +Semantic variables hold not only individual constraints but also relationships between variables. When a `#[Validate]` method's parameter names partially match a constructor's parameter names, the corresponding values are automatically passed: ```php -final readonly class TeenAge +// Email address confirmation match +final readonly class EmailConfirmation { #[Validate] - public function validate(#[Teen] int $age): void + public function validate(string $email, string $confirmEmail): void { - // First, basic Age validation is executed (automatically called via #[Teen]) - // Then, teen-specific rules are added - if ($age < 13) throw new TeenAgeTooYoungException(); - if ($age > 19) throw new TeenAgeTooOldException(); + if ($email !== $confirmEmail) { + throw new EmailMismatchException(); + } } } ``` -This hierarchical approach builds rich semantic hierarchies: - -- `Email` → `CorporateEmail` (corporate domain required) → `ExecutiveEmail` (executive-level constraints) -- `Price` → `DiscountPrice` (discount rate limits) → `MemberPrice` (member pricing rules) -- `Password` → `AdminPassword` (admin requirements) → `SystemPassword` (strict system admin requirements) -- `Address` → `ShippingAddress` (deliverable regions) → `InternationalAddress` (international shipping support) - -Each layer inherits constraints from the previous layer and adds its own unique constraints. Nothing that fails basic `Email` validation can ever exist as `ExecutiveEmail`. This is not merely a combination of validations—it is the **natural refinement of concepts**. - -## Relationship Constraints - -Semantic variables exist not only in isolation but can also hold relationships with other semantic variables as constraints. What's remarkable is **how easy this is to describe**: - ```php -final readonly class UserRegistration +// Start date must be before end date +final readonly class DateRange { - public function __construct( - #[Input] string $email, - #[Input] string $confirmEmail, - #[Input] string $password, - #[Input] string $confirmPassword, - ) { - // Nothing needs to be written here! - // The framework automatically validates relationships + #[Validate] + public function validate(string $startDate, string $endDate): void + { + if ($startDate > $endDate) { + throw new InvalidDateRangeException(); + } } } ``` -The framework automatically discovers and applies validation classes that **partially match** the target constructor's signature. - ```php -// If this exists... -final readonly class EmailConfirmation +// Minimum must not exceed maximum +final readonly class MinMax { #[Validate] - public function validate(string $email, string $confirmEmail): void + public function validate(int $min, int $max): void { - if ($email !== $confirmEmail) { - throw new EmailMismatchException(); + if ($min > $max) { + throw new MinExceedsMaxException(); } } } - -// It's automatically applied to any constructor with $email, $confirmEmail! ``` -Examples of relationship constraints: -- `$startDate` and `$endDate`: Start date must be before end date -- `$minPrice` and `$maxPrice`: Minimum price must be less than or equal to maximum price -- `$email` and `$confirmEmail`: Email address confirmation match required -- `$currentPassword` and `$newPassword`: New password must differ from current one - -Developers define business rules once, and they're automatically applied to all objects with matching signatures. These constraints function as **preconditions** for object existence. Unless preconditions are met, that object cannot even exist. +Define once, and they are automatically applied to any constructor whose argument names match: -## Error Handling - -Multilingual error messages adapt automatically: +```php +// EmailConfirmation + MinMax auto-applied +public function __construct( + string $email, + string $confirmEmail, + int $min, + int $max, +) {} +``` ```php -try { - $userProfile = $becoming(new UserRegistrationInput($data)); -} catch (SemanticVariableException $e) { - $englishMessages = $e->getErrors()->getMessages('en'); - $japaneseMessages = $e->getErrors()->getMessages('ja'); -} +// DateRange auto-applied +public function __construct( + string $startDate, + string $endDate, +) {} ``` -## What Meaning Brings +## Constraints Dwell in Names -**Names are identifiers of meaning and constraints.** This simple principle alone realizes a world rich enough to be called a framework. +The power of names extends beyond format validation: -Semantic Variables make **impossible states impossible**. Invalid email addresses cannot exist as `$email`, negative ages cannot be born as `$age`. Out-of-stock products cannot be ordered as `$orderId`, and addresses outside delivery zones cannot be specified as `$shippingAddress`. +```php +public function __construct( + public string $email, // Format constraint + public float $bodyTemperature, // Value range constraint + public string $inStockItemId, // Business rule constraint +) {} +``` -The type system itself becomes a **domain language**, where each type speaks of what can exist in your business domain. +From formats to value ranges to business rules—names define the conditions for existence. -## Design by Contract +## The Meaning of Failure -Constructor arguments reveal preconditions. Properties reveal postconditions: +When existence fails, the reason must carry meaning: ```php -final readonly class ProcessedOrder +#[Message([ + 'en' => '{email} is not a valid email address.', + 'ja' => '{email}は有効なメールアドレスではありません。' +])] +final readonly class InvalidEmailException extends DomainException { - public function __construct( - #[Input] #[Verified] string $productCode, // Precondition: verified product code - #[Input] int $paymentAmount, // Precondition: payment amount - #[Input] #[Adult] int $age // Precondition: adult age - ) { - // Can only exist when preconditions are satisfied - $this->orderNumber = $this->generateOrderNumber(); - $this->processedAt = new DateTime(); - } - - public string $orderNumber; // Postcondition: order number always exists - public DateTime $processedAt; // Postcondition: processed time always exists + public function __construct(public readonly string $email) {} } ``` -Constructor arguments express **preconditions** (conditions that must be satisfied for this object to exist), while `public readonly` properties express **postconditions** (states this object guarantees). +The framework does not stop at the first exception—it collects **all validation errors**: + +```php +try { + $becoming(new UserRegistrationInput( + name: '', // EmptyNameException + email: 'invalid', // InvalidEmailException + age: -1 // InvalidAgeException + )); +} catch (SemanticVariableException $e) { + $e->getErrors()->getMessages('ja'); + // ['名前は空にできません。', '無効なメールアドレスです。', '無効な年齢です。'] +} +``` -Defensive programming becomes unnecessary. Argument validation, null checks, range verification, inventory confirmation, geographic constraints—semantic variables guarantee all of these. Code can focus on its true purpose: implementing business logic. +The complete reason why existence is impossible becomes clear, in the user's language. -What began as a simple naming convention evolves into hierarchical validation, relationship constraints, external resource integration, building a complete domain guarantee system. **The meaning embedded in names supports the integrity of the entire system.** +In Japan, there is a concept called *kotodama*—the belief that words hold a spiritual power to define reality. Semantic variables are exactly this: the meaning embedded in names supports the integrity of the entire system. --- diff --git a/manuals/1.0/ja/06-semantic-variables.md b/manuals/1.0/ja/06-semantic-variables.md index b7c8ebc..5c1c2a5 100644 --- a/manuals/1.0/ja/06-semantic-variables.md +++ b/manuals/1.0/ja/06-semantic-variables.md @@ -1,6 +1,6 @@ --- layout: docs-ja -title: "6. 意味変数" +title: "7. 意味変数" category: Manual permalink: /manuals/1.0/ja/06-semantic-variables.html --- @@ -11,248 +11,178 @@ permalink: /manuals/1.0/ja/06-semantic-variables.html > >   —スピノザ『エチカ』第1部定理29(1677年) -データの妥当性はどこで保証されるべきでしょうか?コントローラー?モデル?バリデーター? +## 意味と制約 -Be Frameworkの答えは明確です:**名前そのものが制約を持つべき**と考えます。 -`$email`は単なる文字列ではなく、**有効なメールアドレス**であるべきです。`$age`にはマイナスの値は存在できません。 - -意味変数は、情報の識別子であり、意味を表し、制約を持つ**完全な情報モデル**です。 - -## 問題:分散した不完全性 - -従来のアプローチでは、意味の定義が散在しています: - -```php -// コントローラー/model/validator... -if (empty($name)) throw new Exception("error.name.empty"); -if (!filter_var($email, FILTER_VALIDATE_EMAIL)) throw new Exception("error.email.invalid"); - -// messages/ja.yml -error.name.empty: "名前を入力してください" -error.email.invalid: "有効なメールアドレスを入力してください" - -// README.md -// "名前は1-100文字で空白のみは不可..." -``` - -以下の問題が発生します: -- **バリデーション**:コントローラーに散在 -- **エラーメッセージ**:別ファイルで管理 -- **制約ルール**:複数の場所に重複 -- **意味定義**:ドキュメントにのみ存在 - -システムが扱う意味を集中して見ることのできる場所がありません。 - -## 解決法:意味的完全性 - -Be Frameworkは、分散した定義を**完全な情報モデル**として統合します。コンストラクタの引数やクラスのプロパティには、登録された**意味変数**のみを使用できます。 - -## 存在の定義 - -意味変数は専用フォルダにクラスとして定義されます: +`$email`は単なる文字列ではありません。意味変数は情報の識別子であり、意味を表し、制約を持つ完全な情報モデルです: ```php -final readonly class Name +final class Email { #[Validate] - public function validate(string $name): void + public function validate(string $email): void { - if (empty(trim($name))) { - throw new EmptyNameException(); + if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { + throw new InvalidEmailException(); } } } + +// $emailという名前を持つ任意のコンストラクタ引数に自動適用される +public function __construct(string $email) {} ``` -## 検証コンテキスト +一度定義すれば、`$email`という名前のすべてのコンストラクタ引数に自動的に適用されます。`$email`の値が正しいのは偶然ではなく、必然です。正しくなれないものは存在できません。 + +## 名前の装飾 -異なるビジネスコンテキストには異なるルールが適用されることがあります。意味変数は複数の検証コンテキストを自然にサポートします: +同じ名前に属性を加えることで、存在条件をより精密にできます。`#[Validate]`メソッドに属性が付いている場合、コンストラクタ引数の属性とマッチしたときだけ実行されます: ```php -final readonly class ProductCode +// $ageの基本制約(0-150歳) +final readonly class Age { #[Validate] - public function validate(string $code): void - { - // 標準的な商品コード検証(例:8桁の英数字) - if (!preg_match('/^[A-Z0-9]{8}$/', $code)) { - throw new InvalidProductCodeException(); - } - } - - #[Validate] - public function validateLegacy(#[Legacy] string $code): void - { - // レガシーシステム用の緩い検証(例:6-10桁の英数字) - if (!preg_match('/^[A-Z0-9]{6,10}$/', $code)) { - throw new InvalidLegacyProductCodeException(); + public function validate(int $age): void + { + if ($age < 0 || $age > 150) { + throw new InvalidAgeException(); } } + // #[Teen]属性がある場合のみ追加実行される #[Validate] - public function validatePremium(#[Premium] string $code): void - { - // プレミアム商品用の厳格な検証(例:特定のプレフィックス必須) - if (!preg_match('/^PREM[A-Z0-9]{4}$/', $code)) { - throw new InvalidPremiumProductCodeException(); + public function validateTeen(#[Teen] int $age): void + { + if ($age < 13 || $age > 19) { + throw new InvalidTeenAgeException(); } } } ``` -## 失敗の意味 - -存在が失敗したとき、失敗の意味が保持されなければなりません: - ```php -#[Message([ - 'en' => 'Name cannot be empty.', - 'ja' => '名前は空にできません。' -])] -final readonly class EmptyNameException extends DomainException {} -``` +// 基本のAge検証のみ適用 +public function __construct(int $age) {} -フレームワークは最初に投げられる例外だけでなく、**すべての検証エラー**を例外の集合として収集し、なぜ存在できないかの完全な理解を作り出します。 - -## 自然な統合 - -意味変数はコンストラクタで自動的に動作します: - -```php -final readonly class UserProfile -{ - public function __construct( - #[Input] #[English] public string $name, // 英語名として自動検証 - #[Input] string $emailAddress, // メールアドレスとして自動検証 - #[Inject] NameFormatter $formatter - ) { - // この時点で、すべての入力が有効であることが保証されています - } -} +// Age検証 + Teen検証の両方が適用 +public function __construct(#[Teen] int $age) {} ``` -変数名`$name`は`Name`意味変数クラスと、`$emailAddress`は`EmailAddress`意味変数クラスと自動的に関連付けられます。 +同じ`$age`でも、属性によって異なる存在条件が適用されます。 -## 階層的検証 +## 名前が関係を持つ -意味変数は他の意味変数を基盤として構築できます。これはビジネスルールの自然な階層構造を型システムで表現する強力な手法です。 +意味変数は単独の制約だけでなく、変数間の関係も制約として持ちます。`#[Validate]`メソッドの引数名がコンストラクタの引数名と部分マッチすると、対応する値が自動的に渡されます: ```php -final readonly class TeenAge +// メールアドレスの一致確認 +final readonly class EmailConfirmation { #[Validate] - public function validate(#[Teen] int $age): void + public function validate(string $email, string $confirmEmail): void { - // まず基本的なAge検証が実行される(#[Teen]により自動的に呼び出される) - // その後、ティーン固有のルールを追加 - if ($age < 13) throw new TeenAgeTooYoungException(); - if ($age > 19) throw new TeenAgeTooOldException(); + if ($email !== $confirmEmail) { + throw new EmailMismatchException(); + } } } ``` -この階層的アプローチにより、豊かな意味の階層が構築されます: - -- `Email` → `CorporateEmail`(企業ドメイン必須)→ `ExecutiveEmail`(役員レベルの制約) -- `Price` → `DiscountPrice`(割引率制限)→ `MemberPrice`(会員特価ルール) -- `Password` → `AdminPassword`(管理者要件)→ `SystemPassword`(システム管理者の厳格要件) -- `Address` → `ShippingAddress`(配送可能地域)→ `InternationalAddress`(国際配送対応) - -各階層は前の層の制約を継承し、さらに固有の制約を追加します。基本的な`Email`検証が通らないものは、決して`ExecutiveEmail`として存在できません。これは単なる検証の組み合わせではなく、**概念の自然な精緻化**です。 - -## 関係性制約 - -意味変数は単独で存在するだけでなく、他の意味変数との関係性も制約として持てます。特筆すべきは**その記述の容易さ**です: - ```php -final readonly class UserRegistration +// 開始日は終了日より前でなければならない +final readonly class DateRange { - public function __construct( - #[Input] string $email, - #[Input] string $confirmEmail, - #[Input] string $password, - #[Input] string $confirmPassword, - ) { - // 何も書く必要はありません! - // フレームワークが自動的に関係性を検証します + #[Validate] + public function validate(string $startDate, string $endDate): void + { + if ($startDate > $endDate) { + throw new InvalidDateRangeException(); + } } } ``` -フレームワークは、対象のコンストラクタのシグネチャと**部分マッチ**する検証クラスを自動的に発見し、適用します。 - ```php -// これがあれば... -final readonly class EmailConfirmation +// 最小値は最大値以下でなければならない +final readonly class MinMax { #[Validate] - public function validate(string $email, string $confirmEmail): void + public function validate(int $min, int $max): void { - if ($email !== $confirmEmail) { - throw new EmailMismatchException(); + if ($min > $max) { + throw new MinExceedsMaxException(); } } } - -// $email, $confirmEmail を持つ任意のコンストラクタで自動適用される! ``` -関係性制約の例: -- `$startDate` と `$endDate`:開始日は終了日より前でなければならない -- `$minPrice` と `$maxPrice`:最小価格は最大価格以下でなければならない -- `$email` と `$confirmEmail`:メールアドレスの確認一致が必要 -- `$currentPassword` と `$newPassword`:新しいパスワードは現在のものと異なる必要 - -開発者はビジネスルールを一度定義するだけで、該当するシグネチャを持つ全てのオブジェクトで自動的に適用されます。これらの制約は、オブジェクトが存在する**前提条件**として機能します。前提が満たされない限り、そのオブジェクトは存在することすらできません。 +一度定義すれば、引数名がマッチする任意のコンストラクタに自動適用されます: -## エラーハンドリング - -多言語エラーメッセージは自動的に適応します: +```php +// EmailConfirmation + MinMax が自動適用 +public function __construct( + string $email, + string $confirmEmail, + int $min, + int $max, +) {} +``` ```php -try { - $userProfile = $becoming(new UserRegistrationInput($data)); -} catch (SemanticVariableException $e) { - $englishMessages = $e->getErrors()->getMessages('en'); - $japaneseMessages = $e->getErrors()->getMessages('ja'); -} +// DateRange が自動適用 +public function __construct( + string $startDate, + string $endDate, +) {} ``` -## 意味がもたらすもの +## 名前に宿る制約 -**名前は、意味、制約の識別子です。**この単純な原理だけで、意味・制約フレームワークといえるほどの豊かな世界が実現されます。 +名前の力はフォーマット検証にとどまりません: -意味変数により、**不可能な状態が不可能になります**。無効なメールアドレスは`$email`として存在できず、負の年齢は`$age`として生まれることすらありません。在庫のない商品は`$orderId`として注文されることなく、東京23区外の住所は`$city`として配送先に指定されることもありません。 +```php +public function __construct( + public string $email, // フォーマット制約 + public float $bodyTemperature, // 値の範囲制約 + public string $inStockItemId, // ビジネスルール制約 +) {} +``` -型システムそのものが**ドメイン言語**となり、各型があなたのビジネスドメインで何が存在可能かを語ります。 +フォーマットから値の範囲、さらにビジネスルールまで——名前が存在の条件を定義します。 -## 契約による設計 +## 失敗の意味 -コンストラクタの引数は事前条件を表し、プロパティは事後条件を表します: +存在が失敗したとき、その理由は意味を持たなければなりません: ```php -final readonly class ProcessedOrder +#[Message([ + 'en' => '{email} is not a valid email address.', + 'ja' => '{email}は有効なメールアドレスではありません。' +])] +final readonly class InvalidEmailException extends DomainException { - public function __construct( - #[Input] #[Verified] string $productCode, // 事前条件:検証済み商品コード - #[Input] int $paymentAmount, // 事前条件:支払い金額 - #[Input] #[Adult] int $age // 事前条件:成人年齢 - ) { - // 事前条件が満たされた時のみ存在可能 - $this->orderNumber = $this->generateOrderNumber(); - $this->processedAt = new DateTime(); - } - - public string $orderNumber; // 事後条件:注文番号は必ず存在 - public DateTime $processedAt; // 事後条件:処理時刻は必ず存在 + public function __construct(public readonly string $email) {} } ``` -コンストラクタの引数は**事前条件**(このオブジェクトが存在するために満たされなければならない条件)を表し、`public`プロパティは**事後条件**(このオブジェクトが保証する状態)を表現します。 +フレームワークは最初の例外で止まるのではなく、**すべての検証エラー**を収集します: + +```php +try { + $becoming(new UserRegistrationInput( + name: '', // EmptyNameException + email: 'invalid', // InvalidEmailException + age: -1 // InvalidAgeException + )); +} catch (SemanticVariableException $e) { + $e->getErrors()->getMessages('ja'); + // ['名前は空にできません。', '無効なメールアドレスです。', '無効な年齢です。'] +} +``` -防御的プログラミングは不要になります。引数の検証、null チェック、範囲確認、在庫確認、地理的制約—これらはすべて意味変数が保証します。コードは本来の目的であるビジネスロジックの実装に集中できるのです。 +なぜ存在できないかの完全な理由が、ユーザーの言語で明らかになります。 -単なる命名規約から始まった概念が、階層的検証、関係性制約、外部リソース統合まで発展し、完全なドメイン保証システムを構築します。**名前に込められた意味が、システム全体の整合性を支えるのです。** +日本には「言霊」という概念があります。言葉には現実を定義する力が宿るという思想です。意味変数はまさにそれです——名前に込められた意味が、システム全体の整合性を支えます。 --- From b96afb4b34e1cafde5ddb1884067e9bbe9ca9407 Mon Sep 17 00:00:00 2001 From: Akihito Koriyama Date: Thu, 19 Mar 2026 21:05:36 +0900 Subject: [PATCH 04/16] Refactor chapter 8 (Reason Layer) ja/en MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace #[Reason] (non-existent) and #[Input] (incorrect) with #[Inject] - Unify all code examples to shipping domain (ExpressShipping/StandardShipping) - Add "$being as reason" section showing dual role: type discrimination + tool set - Rename "Difference from #[Inject]" to "Difference from Individual Injection" - Remove redundant "State Realization Through Delegation" section - Fix terminology: 内在的性質 → 内在, Immanent property → Immanence - Fix mock reference to Fake - Add chapter 8 design decisions to _design/manual-style.md --- _design/manual-style.md | 31 ++++ .../1.0/en/07-type-driven-metamorphosis.md | 138 -------------- manuals/1.0/en/08-reason-layer.md | 172 +++++++----------- .../1.0/ja/07-type-driven-metamorphosis.md | 156 ---------------- manuals/1.0/ja/08-reason-layer.md | 170 +++++++---------- 5 files changed, 170 insertions(+), 497 deletions(-) delete mode 100644 manuals/1.0/en/07-type-driven-metamorphosis.md delete mode 100644 manuals/1.0/ja/07-type-driven-metamorphosis.md diff --git a/_design/manual-style.md b/_design/manual-style.md index 8081668..fa863dd 100644 --- a/_design/manual-style.md +++ b/_design/manual-style.md @@ -96,6 +96,37 @@ **末尾の洗練**: ヘラクレイトスとの呼応を凝縮。「川が流れるのではなく、流れそのものが川」→ ドメインは時間的存在、という構造を明確化。冒頭(アインシュタイン:時間とドメインは分割できない)から末尾(ヘラクレイトス:存在は変化そのもの)への深まりを実現。 +### 7. 型駆動変容 → 廃止・6章に統合 + +**7章を廃止し6章(変容)に統合**: 7章の内容は6章と大部分が重複していた。6章の「運命の自己決定」で`$being`プロパティと分岐パターンは既に示されており、7章で本当に新しいのは「`$being`の型によって次のクラスが自動選択される」メカニズムの説明だけだった。 + +**統合した要素**: 「型による継続」セクションとして、`$being`の具体的な型が`#[Input]`を持つ次のクラスのコンストラクタに自動マッチされる仕組みを、「運命の自己決定」と「自己組織化パイプライン」の間に挿入。 + +**削除した要素**: +- PaymentAttempt例 → 6章ApplicationReviewと同パターンの重複 +- UserClassification例 → 同上のN択版 +- beingプロパティの説明 → 6章で既出 +- AMD(拡張意思決定)→ 未実装の将来構想。FAQにのみ言及を残す +- 運命の地図 / 実存的問い → 説教的(文体原則「コードに語らせる」に反する) +- 条件分岐の排除 → 1章で既出 +- 型システムとの統合 → まとめだが新情報なし + +### 8. 存在理由層 (08-reason-layer) + +**`#[Reason]` → `#[Inject]`**: 存在理由層はフレームワーク固有の属性ではなく、`#[Inject]`を使った設計パターン。`#[Reason]`という存在しない属性をすべて`#[Inject]`に置換。EN版の`#[Input]`(存在理由オブジェクトに誤って使用されていた)も`#[Inject]`に統一。 + +**FormalStyle/CasualStyle挨拶例 → 配送ドメインに統一**: 人工的な挨拶スタイルの例を、配送ドメイン(`ExpressShipping`, `StandardShipping`)に差し替え。章内のすべてのコード例を配送ドメインで統一。存在理由クラスの定義では、各配送方式が固有のメソッド群を持つことを示す(速達: `guaranteeDeliveryBy`, `realTimeTrack` / 通常: `estimateDeliveryWindow`)。 + +**「型マッチングの理由」セクションの再構成**: 二重構造(型マッチング+存在理由)をやめ、raison d'êtreの説明から始める。ただし`$being`としての型判別と道具セット提供の二重役割は「$beingとしての存在理由」セクションとして残す。6章の「型による継続」が仕組みを説明し、8章は存在理由オブジェクトが判別と道具提供を統合するパターンを示す。 + +**「#[Inject]との違い」→「個別注入との違い」**: 存在理由層自体が`#[Inject]`を使う以上、「#[Inject]との違い」は誤解を招く。複数の`#[Inject]`をバラバラに使うパターンとの対比であることを見出しで明確化。 + +**「委譲による状態実現」セクションの削除**: セクション1のコード例が既に委譲を示しているため、独立セクションとしては冗長。締めの一文を「個別注入との違い」末尾に統合。 + +**用語統一**: `内在的性質` → `内在`、`Immanent property` → `Immanence`。2-6章と同じルール。 + +**日英属性の不一致修正**: JA版は`#[Reason]`、EN版は`#[Input]`と、存在理由オブジェクトの属性がバラバラだった。どちらも`#[Inject]`に統一。 + --- # 文体・構成の原則 diff --git a/manuals/1.0/en/07-type-driven-metamorphosis.md b/manuals/1.0/en/07-type-driven-metamorphosis.md deleted file mode 100644 index 2922e1c..0000000 --- a/manuals/1.0/en/07-type-driven-metamorphosis.md +++ /dev/null @@ -1,138 +0,0 @@ ---- -layout: docs-en -title: "7. Type-Driven Metamorphosis" -category: Manual -permalink: /manuals/1.0/en/07-type-driven-metamorphosis.html ---- - -# Type-Driven Metamorphosis - -> "The Tao gives birth to one, one gives birth to two, two gives birth to three, three gives birth to all things" -> ->   —Laozi, *Tao Te Ching*, Chapter 42 (6th century BCE) - -Type-driven metamorphosis enables objects to choose from multiple possible types based on conditions. Multiple classes are declared as arrays using the `#[Be()]` attribute, with the selection expressed through the being property: - -```php -#[Be([Success::class, Failure::class])] -final readonly class PaymentAttempt -{ - public Success|Failure $being; - - public function __construct( - #[Input] Money $amount, - #[Input] CreditCard $card, - #[Inject] PaymentGateway $gateway - ) { - $result = $gateway->process($amount, $card); - - // Branching based on results - $this->being = $result->isSuccessful() - ? new Success($result) - : new Failure($result->getError()); - } -} -``` - -## The Being Property - -The `$being` property indicates the next transformation destination: - -```php -public Success|Failure|Pending $being; -``` - -Classes are chosen when this type signature matches the constructor of the next class. -For example, if `$being` is of type `Success`, a class with the following constructor would be selected: - -```php -class NextStep { - public function __construct(#[Input] Success $being) { -``` - -`#[Be]` completely expresses all possibilities of an object. Types become the specification for workflows and use cases. - -## Multiple Type Selection Example - -```php -#[Be([VIPUser::class, RegularUser::class, SuspendedUser::class])] -final readonly class UserClassification -{ - public VIPUser|RegularUser|SuspendedUser $being; - - public function __construct( - #[Input] UserActivity $activity, - #[Input] array $violations, - #[Inject] UserPolicy $policy - ) { - $this->being = match (true) { - $policy->shouldSuspend($violations) => new SuspendedUser($violations), - $activity->qualifiesForVIP() => new VIPUser($activity), - default => new RegularUser($activity) - }; - } -} -``` - -## Continuation Processing Mechanism - -The advantage of type-driven processing lies in automatic continuation processing: - -```php -$evaluation = $becoming(new UserInput($data)); -$notification = $becoming($evaluation); // $evaluation->being is automatically selected -``` - -The framework detects the `$being` property and performs the next processing based on its type. External conditional branching becomes unnecessary. - -## Extended Decision-Making Prospects - -⚠️ **Note**: AMD (Advanced Decision-Making) is currently an unimplemented future concept. - -Beyond deterministic judgment, a new paradigm that embraces uncertainty is being prepared: - -```php -// Future concept -#[Accept] // Unimplemented: delegation to experts -#[Be([Approved::class, Rejected::class, Undetermined::class])] -final readonly class ComplexDecision -{ - public Approved|Rejected|Undetermined $being; - - // Extended decision-making through AI-human collaboration -} -``` - -A decision system where determinable things are decided by types, and indeterminate things are delegated to experts. - -## Elimination of Control Structures - -Be Framework eliminates traditional "complex control structures within methods". The framework follows flows declared with `#[Be]` and selects the next class through type matching. - -Traditional complex conditional branching: - -```php -if ($score > 800) { - return new Approved($amount); -} elseif ($score < 400) { - return new Rejected("Low score"); -} else { - return new Review($amount); -} -``` - -In type-driven metamorphosis, these are expressed as union types: - -```php -public Approved|Rejected|Review $being; -``` - -## Integration with Type System - -Type-driven metamorphosis integrates complex decision logic into the type system. Union types make possible results explicit, while constructors handle the actual branching. This makes decision logic understandable and maintainable code. - -From the simple principle "if types match, proceed to the next", a rich workflow system that handles real-world complexity is constructed. - ---- - -No existence exists without reason. Let's explore the [Reason Layer](./08-reason-layer.html) ➡️ diff --git a/manuals/1.0/en/08-reason-layer.md b/manuals/1.0/en/08-reason-layer.md index 1281b04..1d5fc75 100644 --- a/manuals/1.0/en/08-reason-layer.md +++ b/manuals/1.0/en/08-reason-layer.md @@ -11,126 +11,123 @@ permalink: /manuals/1.0/en/08-reason-layer.html > >   —Leibniz, *Principle of Sufficient Reason* (1714) -## Why This Name? +## Reason for Existence -The Reason Layer has two meanings of "reason": +`ExpressDelivery` can exist as such because it has express shipping capabilities. `StandardDelivery` can exist as such because it has standard shipping capabilities. This foundation for "why it can be in that existence" is the **raison d'être**. -### 1. Reason for Type Matching - -First, the type itself that serves as the basis for the framework to determine the next transformation destination: +The Reason Layer is a design pattern that expresses this raison d'être as a single object. ```php -final readonly class CasualGreeting +final readonly class ExpressDelivery { - public string $greeting; - public string $emoji; + public Fee $fee; public function __construct( - #[Input] public string $name, // Immanent property - #[Input] public CasualStyle $being // This being CasualStyle type + #[Input] OrderData $order, // Immanence + #[Inject] ExpressShipping $reason // Reason for existence ) { - // $being transformed to CasualGreeting because it's CasualStyle type - $this->greeting = $this->being->casualGreeting($name); - $this->emoji = $this->being->casualEmoji(); + $this->fee = $reason->calculateFee($order->weight); } } ``` -The **type itself** `CasualStyle $being` is the reason why it becomes `CasualGreeting`. The framework reads this type and automatically selects the corresponding transformation destination. +`ExpressShipping` is the raison d'être of `ExpressDelivery`. It provides the complete tool set needed for express delivery. -### 2. Reason for Existence +## Reason as $being -Next, the reason as the foundation for why an object can be in that existence: +When a reason object is passed as `$being`, it takes on an additional role. Its **type** serves as the basis for determining the transformation destination, while simultaneously providing the methods specific to that mode of existence. ```php -final readonly class FormalGreeting +final readonly class ExpressDelivery +{ + public Fee $fee; + + public function __construct( + #[Input] OrderData $order, + #[Input] ExpressShipping $being // Type determines transformation and provides express-specific methods + ) { + $this->fee = $being->calculateFee($order->weight); + } +} + +final readonly class StandardDelivery { - public string $greeting; - public string $businessCard; - + public Fee $fee; + public function __construct( - #[Input] string $name, // Immanent property - #[Reason] FormalStyle $being // Reason for existence + #[Input] OrderData $order, + #[Input] StandardShipping $being // Type determines transformation and provides standard-specific methods ) { - // FormalStyle can be FormalStyle because it can do formalGreeting() and formalBusinessCard() - $this->greeting = $being->formalGreeting($name); - $this->businessCard = $being->formalBusinessCard($name); + $this->fee = $being->calculateFee($order->weight); } } ``` -`FormalGreeting` can exist as `FormalGreeting` because `FormalStyle` provides the necessary behaviors. This is the reason for existence. +The type `ExpressShipping $being` itself is the reason why it becomes `ExpressDelivery`. The framework reads this type and automatically selects the corresponding transformation destination. ## Defining Reason Classes -Reason classes provide methods that realize specific modes of existence: +Reason classes bundle the services necessary to realize a specific mode of existence: ```php namespace App\Reason; -final readonly class FormalStyle +final readonly class ExpressShipping { - public function formalGreeting(string $name): string - { - return "Good morning, Mr./Ms. {$name}."; - } - - public function formalBusinessCard(string $name): string + public function __construct( + private PriorityCarrier $carrier, + private RealTimeTracker $tracker, + ) {} + + public function calculateFee(Weight $weight): Fee // Express rate { - return "【{$name}】\nI would like to extend my formal greetings."; + return $this->carrier->expressFee($weight); } -} -final readonly class CasualStyle -{ - public function casualGreeting(string $name): string + public function guaranteeDeliveryBy(Address $address): \DateTimeImmutable // Guaranteed delivery date { - return "Hey, {$name}!"; + return $this->carrier->guaranteedDate($address); } - - public function casualMessage(string $name): string + + public function realTimeTrack(TrackingId $id): TrackingStatus // Real-time tracking { - return "Hi {$name}! 😊 Nice to meet you!"; + return $this->tracker->realTimeStatus($id); } } ``` -## Reason for Existence as Raison d'être - -The Reason Layer provides the **raison d'être** of objects. - ```php -final readonly class ValidatedUser +final readonly class StandardShipping { public function __construct( - #[Input] string $email, - #[Input] ValidationReason $raisonDEtre // The raison d'être of this existence - ) { - // ValidationReason provides the raison d'être for ValidatedUser + private RegularCarrier $carrier, + private BatchTracker $tracker, + ) {} + + public function calculateFee(Weight $weight): Fee // Standard rate + { + return $this->carrier->standardFee($weight); + } + + public function estimateDeliveryWindow(Address $address): DateRange // Estimated delivery window + { + return $this->carrier->estimateWindow($address); } } ``` -**raison d'être** means: -- Why an object can exist in that state -- The raison d'être of `ValidatedUser` is validation capability -- The raison d'être of `SavedUser` is saving capability -- The raison d'être of `DeletedUser` is deletion/archival capability - -Reason objects provide the tool set necessary for an object to exist in that state. This is the origin of the name "Reason Layer" in the Be Framework. +## Difference from Individual Injection -## Difference from #[Inject] +The Reason Layer uses `#[Inject]`. So how does it differ from using multiple `#[Inject]` attributes separately? -The unique value of the Reason Layer becomes clear when compared to traditional dependency injection: - -**Traditional Inject**: +**Individual injection**: ```php public function __construct( - #[Input] string $email, - #[Inject] EmailValidator $emailValidator, - #[Inject] PasswordChecker $passwordChecker, - #[Inject] SecurityAuditor $auditor, - #[Inject] DatabaseSaver $saver + #[Input] OrderData $order, + #[Inject] PriorityCarrier $carrier, + #[Inject] RealTimeTracker $tracker, + #[Inject] InsuranceService $insurance, + #[Inject] DeliveryScheduler $scheduler ) { // Using scattered tools individually } @@ -139,44 +136,15 @@ public function __construct( **Reason Layer**: ```php public function __construct( - #[Input] string $email, - #[Input] UserValidationReason $reason // Related tools bundled as reason for existence + #[Input] OrderData $order, + #[Inject] ExpressShipping $reason // Related tools bundled as reason for existence ) { - // A complete tool set for becoming ValidatedUser is provided - $this->result = $reason->validateUser($email, $this); + $this->fee = $reason->calculateFee($order->weight); } ``` -**Differences**: -- **Inject**: Individual tools injected separately -- **Reason Layer**: Provided as a semantically coherent "tool set for achieving that state" - -**Value**: -- **Conceptual coherence**: "What is needed to become ValidatedUser?" is clear -- **Simplified testing**: Mock one reason object instead of many -- **Separation of concerns**: Related tools are consolidated in one place - -## State Realization Through Delegation - -In the Reason Layer, objects delegate the realization of their state to reason objects: - -```php -final readonly class SavedUser -{ - public function __construct( - #[Input] UserData $data, - #[Input] SaveReason $reason // Receive reason for existence - ) { - // Delegate saving process to reason for existence - $this->result = $reason->saveUser($data); - } -} -``` - -Objects themselves declare "what to become", while reason objects realize "how to achieve that state". This separation clearly divides state definition from realization means. - -`SavedUser` requires a saving tool set, `ValidatedUser` requires a validation tool set. Reason objects clearly organize "what is needed to achieve this state?" and follow the single responsibility principle, making tests concise as well. +"What is needed to become ExpressDelivery?" — a single reason object answers that question. Objects themselves declare "what to become", while reason objects realize "how to achieve that state". --- -The inability to exist is itself an existence. Learn how to handle this in [Validation and Error Handling](./09-error-handling.html) ➡️ \ No newline at end of file +The inability to exist is itself an existence. Learn how to handle this in [Validation and Error Handling](./09-error-handling.html) ➡️ diff --git a/manuals/1.0/ja/07-type-driven-metamorphosis.md b/manuals/1.0/ja/07-type-driven-metamorphosis.md deleted file mode 100644 index 7b562d1..0000000 --- a/manuals/1.0/ja/07-type-driven-metamorphosis.md +++ /dev/null @@ -1,156 +0,0 @@ ---- -layout: docs-ja -title: "7. 型駆動変容" -category: Manual -permalink: /manuals/1.0/ja/07-type-driven-metamorphosis.html ---- - -# 型駆動変容 - -> 「道生一、一生二、二生三、三生万物」 -> ->   —老子『道徳経』第四十二章(紀元前6世紀) - -## 型駆動による変容 - -型駆動変容では、オブジェクトが複数の可能な型から条件に応じて選択します。`#[Be()]`属性で複数のクラスを配列として宣言し、beingプロパティでその選択を表現します: - -```php -#[Be([Success::class, Failure::class])] -final readonly class PaymentAttempt -{ - public Success|Failure $being; - - public function __construct( - #[Input] Money $amount, - #[Input] CreditCard $card, - #[Inject] PaymentGateway $gateway - ) { - $result = $gateway->process($amount, $card); - - // 結果に応じた分岐 - $this->being = $result->isSuccessful() - ? new Success($result) - : new Failure($result->getError()); - } -} -``` - -## beingプロパティ - -`$being`プロパティは次の変容先を示すプロパティです: - -```php -public Success|Failure|Pending $being; -``` - -次のクラスのコンストラクタでこの型シグネチャがマッチするクラスが選ばれます。 -例えば`$being`が`Success`型なら、以下のコンストラクタを持つクラスが選択されます: - -```php -class NextStep { - public function __construct(#[Input] Success $being) { -``` - -`#[Be]`がオブジェクトの全ての可能性を完全に表現します。型がワークフローやユースケースの仕様になります。 - -## 複数型の選択例 - -```php -#[Be([VIPUser::class, RegularUser::class, SuspendedUser::class])] -final readonly class UserClassification -{ - public VIPUser|RegularUser|SuspendedUser $being; - - public function __construct( - #[Input] UserActivity $activity, - #[Input] array $violations, - #[Inject] UserPolicy $policy - ) { - $this->being = match (true) { - $policy->shouldSuspend($violations) => new SuspendedUser($violations), - $activity->qualifiesForVIP() => new VIPUser($activity), - default => new RegularUser($activity) - }; - } -} -``` - -## 継続処理の仕組み - -型駆動処理の利点は、自動的な継続処理にあります: - -```php -$evaluation = $becoming(new UserInput($data)); -$notification = $becoming($evaluation); // $evaluation->beingが自動選択される -``` - -フレームワークは`$being`プロパティを検出し、その型に応じて次の処理を行います。外部の条件分岐は不要になります。 - -## 拡張意思決定の展望 - -⚠️ **注記**: AMD(拡張意思決定)は現在未実装の将来構想です。 - -確定的判断を超えて、不確実性を受容する新しいパラダイムが準備されています: - -```php -// 将来構想 -#[Accept] // 未実装:専門家への委譲 -#[Be([Approved::class, Rejected::class, Undetermined::class])] -final readonly class ComplexDecision -{ - public Approved|Rejected|Undetermined $being; - - // AIと人間の協調による拡張意思決定 -} -``` - -確定できるものは型で決定し、不確定なものは専門家に委譲する意思決定システムです。 - -## 運命の地図としての型 (Destiny Map) - -Type-Driven Metamorphosis(型駆動変容)において、Union型 (`Success|Failure`) は単なる「複数の型の可能性」ではありません。それはオブジェクトの「運命の地図」です。 - -### 実存的問い (Existential Question) - -従来のプログラミングでは、外部のコントローラーが `if` 文を使って「もしAなら、こっちに行け」と命令(Routing)していました。 -Be Frameworkでは、この主従関係が逆転します。オブジェクト自身がコンストラクタ内で**「私は誰なのか?(Who am I?)」**という実存の問いに向き合います。 - -* **Destiny (運命)**: `public readonly Success|Failure $being` - * このプロパティ定義は、「私の未来はこの2つのどちらかである」という予言です。 -* **Self-Discovery (自己発見)**: `$this->being = ...` - * コンストラクタの中で、自身のデータ(Immanence)と環境(Inject)を照らし合わせ、自分が何者になったのかを発見します。 - -「制御(Routing)」を捨てて「自己発見(Discovery)」に委ねることで、コードから条件分岐の複雑さが消え去り、あるのは純粋な「存在の定義」だけになります。 - -## 条件分岐の排除 - -Be Frameworkは従来の"メソッドの中にある複雑な制御構造"を排除します。フレームワークは`#[Be]`で宣言された流れに従い、型マッチングで次のクラスを選択します。 - -従来の複雑な条件分岐: - -```php -if ($score > 800) { - return new Approved($amount); -} elseif ($score < 400) { - return new Rejected("Low score"); -} else { - return new Review($amount); -} -``` - -型駆動変容では、これらがユニオン型で表現されます: - -```php -public Approved|Rejected|Review $being; -``` - -## 型システムとの統合 - -型駆動変容により、複雑な決定ロジックが型システムに統合されます。ユニオン型が可能な結果を明示し、コンストラクタが実際の分岐を処理します。これにより、決定ロジックが理解しやすく、保守しやすいコードになります。 - -「型がマッチすれば次に進む」という単純な原理から、現実の複雑さに対応する豊かなワークフローシステムが構築されます。 - ---- - -存在する理由のない存在はありません。[存在理由層](./08-reason-layer.html)を見ていきましょう ➡️ diff --git a/manuals/1.0/ja/08-reason-layer.md b/manuals/1.0/ja/08-reason-layer.md index f3dbf02..204d489 100644 --- a/manuals/1.0/ja/08-reason-layer.md +++ b/manuals/1.0/ja/08-reason-layer.md @@ -11,126 +11,123 @@ permalink: /manuals/1.0/ja/08-reason-layer.html > >   —ライプニッツ『充足理由律』(1714年) -## なぜこの名前か? +## 存在の理由 -存在理由層には2つの「理由」があります。 +`ExpressDelivery`がその存在でいられるのは、速達配送の能力を持っているからです。`StandardDelivery`がその存在でいられるのは、通常配送の能力を持っているからです。この「なぜその存在でいられるのか」の根拠が、**raison d'être**(レーゾンデートル:存在理由)です。 -### 1. 型マッチングの理由 - -まず、フレームワークが次の変容先を決定する際の根拠となる型: +存在理由層は、このraison d'êtreを一つのオブジェクトとして表現する設計パターンです。 ```php -final readonly class CasualGreeting +final readonly class ExpressDelivery { - public string $greeting; - public string $emoji; + public Fee $fee; public function __construct( - #[Input] public string $name, // 内在的性質 - #[Input] public CasualStyle $being // この$beingがCasualStyle型であること + #[Input] OrderData $order, // 内在 + #[Inject] ExpressShipping $reason // 存在理由 ) { - // $beingがCasualStyle型だからCasualGreetingに変容した - $this->greeting = $this->being->casualGreeting($name); - $this->emoji = $this->being->casualEmoji(); + $this->fee = $reason->calculateFee($order->weight); } } ``` -`CasualStyle $being`という**型そのもの**が、なぜ`CasualGreeting`になるのかの理由です。フレームワークはこの型を読み取り、対応する変容先を自動選択します。 +`ExpressShipping`が`ExpressDelivery`のraison d'êtreです。速達配送に必要な道具一式をまとめて提供します。 -### 2. 存在の理由 +## $beingとしての存在理由 -次に、オブジェクトがその存在でいるための根拠としての理由: +存在理由オブジェクトは`$being`として渡されることで、もう一つの役割を担います。その**型**が変容先の判別根拠になると同時に、その存在様式に固有のメソッド群を提供します。 ```php -final readonly class FormalGreeting +final readonly class ExpressDelivery +{ + public Fee $fee; + + public function __construct( + #[Input] OrderData $order, + #[Input] ExpressShipping $being // 型が変容先を決定し、速達固有のメソッドを提供 + ) { + $this->fee = $being->calculateFee($order->weight); + } +} + +final readonly class StandardDelivery { - public string $greeting; - public string $businessCard; - + public Fee $fee; + public function __construct( - #[Input] string $name, // 内在的性質 - #[Reason] FormalStyle $being // 存在理由 + #[Input] OrderData $order, + #[Input] StandardShipping $being // 型が変容先を決定し、通常配送固有のメソッドを提供 ) { - // FormalStyleはformalGreeting()やformalBusinessCard()ができるからこそFormalStyleでいられる - $this->greeting = $being->formalGreeting($name); - $this->businessCard = $being->formalBusinessCard($name); + $this->fee = $being->calculateFee($order->weight); } } ``` -`FormalGreeting`が`FormalGreeting`として存在できるのは、`FormalStyle`が必要な振る舞いを提供するからです。これが存在の理由です。 +`ExpressShipping $being`という型そのものが、なぜ`ExpressDelivery`になるのかの理由です。フレームワークはこの型を読み取り、対応する変容先を自動選択します。 ## 存在理由クラスの定義 -存在理由クラスは、特定の存在様式を実現するメソッドを提供します: +存在理由クラスは、特定の存在様式を実現するために必要なサービスをまとめたものです: ```php namespace App\Reason; -final readonly class FormalStyle +final readonly class ExpressShipping { - public function formalGreeting(string $name): string - { - return "おはようございます、{$name}様。"; - } - - public function formalBusinessCard(string $name): string + public function __construct( + private PriorityCarrier $carrier, + private RealTimeTracker $tracker, + ) {} + + public function calculateFee(Weight $weight): Fee // 速達料金 { - return "【{$name}様】\n正式なご挨拶をさせていただきます。"; + return $this->carrier->expressFee($weight); } -} -final readonly class CasualStyle -{ - public function casualGreeting(string $name): string + public function guaranteeDeliveryBy(Address $address): \DateTimeImmutable // 配達日保証 { - return "やあ、{$name}!"; + return $this->carrier->guaranteedDate($address); } - - public function casualMessage(string $name): string + + public function realTimeTrack(TrackingId $id): TrackingStatus // リアルタイム追跡 { - return "Hi {$name}! 😊 よろしく!"; + return $this->tracker->realTimeStatus($id); } } ``` -## raison d'être としての存在理由 - -存在理由層は、オブジェクトの**raison d'être**(レーゾンデートル:存在理由)を提供します。 - ```php -final readonly class ValidatedUser +final readonly class StandardShipping { public function __construct( - #[Input] string $email, - #[Reason] ValidationReason $raisonDEtre // この存在の raison d'être - ) { - // ValidationReasonが、ValidatedUserの存在理由を提供 + private RegularCarrier $carrier, + private BatchTracker $tracker, + ) {} + + public function calculateFee(Weight $weight): Fee // 通常料金 + { + return $this->carrier->standardFee($weight); + } + + public function estimateDeliveryWindow(Address $address): DateRange // 配達期間の見積もり + { + return $this->carrier->estimateWindow($address); } } ``` -**raison d'être**とは: -- なぜそのオブジェクトがその存在でいられるのか -- `ValidatedUser`の raison d'être は検証能力 -- `SavedUser`の raison d'être は保存能力 -- `DeletedUser`の raison d'être は削除・アーカイブ能力 - -存在理由オブジェクトは、そのオブジェクトがその状態でいるために必要な道具セットを提供します。これがBeフレームワークの「存在理由層」の名前の由来です。 +## 個別注入との違い -## #[Inject]との違い +存在理由層は`#[Inject]`を使います。では複数の`#[Inject]`をバラバラに使う場合と何が違うのでしょうか。 -存在理由層の独自価値は、従来の依存性注入との比較で明確になります: - -**従来のInject**: +**個別の注入**: ```php public function __construct( - #[Input] string $email, - #[Inject] EmailValidator $emailValidator, - #[Inject] PasswordChecker $passwordChecker, - #[Inject] SecurityAuditor $auditor, - #[Inject] DatabaseSaver $saver + #[Input] OrderData $order, + #[Inject] PriorityCarrier $carrier, + #[Inject] RealTimeTracker $tracker, + #[Inject] InsuranceService $insurance, + #[Inject] DeliveryScheduler $scheduler ) { // バラバラの道具を個別に使用 } @@ -139,43 +136,14 @@ public function __construct( **存在理由層**: ```php public function __construct( - #[Input] string $email, - #[Reason] UserValidationReason $reason // 関連道具がまとまった存在理由 + #[Input] OrderData $order, + #[Inject] ExpressShipping $reason // 関連道具がまとまった存在理由 ) { - // ValidatedUserになるための道具一式が提供される - $this->result = $reason->validateUser($email, $this); + $this->fee = $reason->calculateFee($order->weight); } ``` -**違い**: -- **Inject**: 個別の道具を別々に注入 -- **存在理由層**: 「その状態になるための道具セット」として意味的にまとまって提供 - -**価値**: -- **概念的まとまり**: 「ValidatedUserになるには何が必要?」が明確 -- **テストの簡素化**: 存在理由オブジェクト一つをモックすれば済む -- **関心の分離**: 関連する道具が一か所に集約 - -## 委譲による状態実現 - -存在理由層では、オブジェクトが自身の状態実現を存在理由に委譲します: - -```php -final readonly class SavedUser -{ - public function __construct( - #[Input] UserData $data, - #[Reason] SaveReason $reason // 存在理由を受け取り - ) { - // 保存処理を存在理由に委譲 - $this->result = $reason->saveUser($data); - } -} -``` - -オブジェクト自身は「何になるか」を宣言し、存在理由は「どうやってその状態になるか」を実現します。この分離により、状態定義と実現手段が明確に分けられます。 - -`SavedUser`になるためには保存用の道具セットが、`ValidatedUser`になるためには検証用の道具セットが必要です。存在理由オブジェクトは「この状態になるには何が必要か?」を明確に整理し、単一責任原則に従うため、テストも簡潔になります。 +「ExpressDeliveryになるには何が必要か?」という問いに、存在理由オブジェクト一つが答えます。オブジェクト自身は「何になるか」を宣言し、存在理由は「どうやってその状態になるか」を実現します。 --- From e36617e059dbd1710dc8c7bf851482f30b7df110 Mon Sep 17 00:00:00 2001 From: Akihito Koriyama Date: Thu, 19 Mar 2026 22:19:00 +0900 Subject: [PATCH 05/16] Refactor chapter 9 (Semantic Exceptions) ja/en - Rename from Error Handling to Semantic Exceptions - Consolidate failure content from chapter 6 into chapter 9 - Replace chapter 6 failure section with bridge text - Unify ja/en structure: 6 sections, matching line numbers - Remove JA-only verbose sections (semantic log, dev vs prod, tests, revolution) - Add structured data logging example from EN version --- _design/manual-style.md | 18 +++ manuals/1.0/en/06-semantic-variables.md | 36 +----- manuals/1.0/en/09-error-handling.md | 57 ++++---- manuals/1.0/ja/06-semantic-variables.md | 36 +----- manuals/1.0/ja/09-error-handling.md | 164 ++++++++---------------- 5 files changed, 100 insertions(+), 211 deletions(-) diff --git a/_design/manual-style.md b/_design/manual-style.md index fa863dd..3ba52c5 100644 --- a/_design/manual-style.md +++ b/_design/manual-style.md @@ -127,6 +127,24 @@ **日英属性の不一致修正**: JA版は`#[Reason]`、EN版は`#[Input]`と、存在理由オブジェクトの属性がバラバラだった。どちらも`#[Inject]`に統一。 +### 9. 意味例外 (09-error-handling) + +**タイトル変更**: 「エラーハンドリング」→「意味例外」(EN: Error Handling → Semantic Exceptions)。permalinkはそのまま維持。エラーハンドリングは手段の名前、意味例外は概念の名前。章が語るのは概念。 + +**6章からの内容移動**: 6章「失敗の意味」セクション(`#[Message]`属性、`SemanticVariableException`のcatchパターン、言霊/kotodama)をすべて9章に集約。6章には橋渡し一文のみ残す。意味変数の章は「名前の力」まで、失敗したときの扱いは意味例外の章で。 + +**JA固有の削除**: +- 意味ログ統合 → 10章の内容 +- 開発 vs プロダクション → `app()->environment('local')` はフレームワーク非依存の実装詳細 +- テスト → コード片だけで文脈不足 +- 革命 → 説教的(文体原則「コードに語らせる」に反する) + +**構成の統一**: 日英で同一構成に統一(エピグラフのみ意図的に異なる:JA=孔子、EN=エジソン)。EN版をベースに、JA版の良い部分を取り込む形で統合。 + +**コード例の修正**: `UserProfile` → 使用箇所なし(既に2章で`ValidatedUser`に変更済み)。`UserValidation`コード例を日英で統一。 + +**エピグラフの意図**: JA版は孔子「過ちて改めざる、これを過ちという」(過ちの質=意味の問題)、EN版はエジソン「1万通りのうまくいかない方法を見つけた」(失敗は情報)。どちらも「失敗に意味がある」を異なる角度から照射。日英で異なるエピグラフにしたのは遊び。 + --- # 文体・構成の原則 diff --git a/manuals/1.0/en/06-semantic-variables.md b/manuals/1.0/en/06-semantic-variables.md index e952307..585b7ac 100644 --- a/manuals/1.0/en/06-semantic-variables.md +++ b/manuals/1.0/en/06-semantic-variables.md @@ -150,40 +150,8 @@ public function __construct( From formats to value ranges to business rules—names define the conditions for existence. -## The Meaning of Failure - -When existence fails, the reason must carry meaning: - -```php -#[Message([ - 'en' => '{email} is not a valid email address.', - 'ja' => '{email}は有効なメールアドレスではありません。' -])] -final readonly class InvalidEmailException extends DomainException -{ - public function __construct(public readonly string $email) {} -} -``` - -The framework does not stop at the first exception—it collects **all validation errors**: - -```php -try { - $becoming(new UserRegistrationInput( - name: '', // EmptyNameException - email: 'invalid', // InvalidEmailException - age: -1 // InvalidAgeException - )); -} catch (SemanticVariableException $e) { - $e->getErrors()->getMessages('ja'); - // ['名前は空にできません。', '無効なメールアドレスです。', '無効な年齢です。'] -} -``` - -The complete reason why existence is impossible becomes clear, in the user's language. - -In Japan, there is a concept called *kotodama*—the belief that words hold a spiritual power to define reality. Semantic variables are exactly this: the meaning embedded in names supports the integrity of the entire system. +When constraints dwelling in names are violated, existence fails. Learn how to handle this in [Semantic Exceptions](./09-error-handling.html). --- -Objects know their own next transformation. The mechanism, [Type-Driven Metamorphosis](./07-type-driven-metamorphosis.html) ➡️ +No existence exists without reason. [Reason Layer](./08-reason-layer.html) ➡️ diff --git a/manuals/1.0/en/09-error-handling.md b/manuals/1.0/en/09-error-handling.md index f16ee9d..8934884 100644 --- a/manuals/1.0/en/09-error-handling.md +++ b/manuals/1.0/en/09-error-handling.md @@ -1,11 +1,11 @@ --- layout: docs-en -title: "9. Error Handling" +title: "9. Semantic Exceptions" category: Manual permalink: /manuals/1.0/en/09-error-handling.html --- -# Error Handling +# Semantic Exceptions > "I have not failed. I've just found 10,000 ways that won't work" > @@ -13,15 +13,17 @@ permalink: /manuals/1.0/en/09-error-handling.html ## Meaningful Failures -In Be Framework, errors are not mere "failures" but **specific reasons why existence is impossible**. We use semantic exceptions instead of generic ones: +Generic exceptions tell **what happened**: ```php -// Traditional generic error catch (Exception $e) { echo $e->getMessage(); // "Validation failed" } +``` + +In contrast, semantic exceptions tell **why existence is impossible**: -// Semantic exceptions +```php catch (SemanticVariableException $e) { foreach ($e->getErrors()->exceptions as $exception) { echo get_class($exception) . ": " . $exception->getMessage(); @@ -33,7 +35,7 @@ catch (SemanticVariableException $e) { ## Domain Exception Classes -In Be Framework, all exceptions inherit from `DomainException`: +All exceptions inherit from `DomainException`. Technical exceptions (`RuntimeException`, `InvalidArgumentException`, etc.) are not used. Failures are always expressed as **failures with domain meaning**: ```php abstract class DomainException extends Exception {} @@ -48,18 +50,13 @@ final readonly class InvalidEmailException extends DomainException } } -final readonly class AgeTooYoungException extends DomainException -{ - public function __construct(public int $age, public int $min = 13) - { - parent::__construct("Age insufficient: {$age} years (minimum {$min} years)"); - } -} +// Age-related existence failures +abstract class AgeException extends DomainException {} +final readonly class NegativeAgeException extends AgeException {} +final readonly class AgeTooHighException extends AgeException {} ``` -Since all exceptions are domain exceptions, technical exceptions (`RuntimeException`, `InvalidArgumentException`, etc.) are not used. Failures are always expressed as **failures with domain meaning**. - -Domain exceptions hold not just messages but **structured data**. From the `$invalidEmail` property, programs can access the invalid email address value and utilize it for various purposes: human-readable display, API JSON responses, AI analysis, etc. +Domain exceptions hold not just messages but **structured data**. From the `$invalidEmail` property, programs can access the invalid email address value—for display, API responses, logging, and more: ```php catch (InvalidEmailException $e) { @@ -72,9 +69,9 @@ catch (InvalidEmailException $e) { } ``` -## Multilingual Error Messages +## Multilingual Messages -The `#[Message]` attribute enables multilingual error messages: +The `#[Message]` attribute lets exceptions speak in the user's language: ```php #[Message([ @@ -94,36 +91,36 @@ final readonly class AgeTooYoungException extends DomainException } ``` -## Automatic Collection of All Errors +## Error Collection -The framework collects **all validation errors** before throwing an exception: +The framework does not stop at the first error—it collects **all validation errors**: ```php try { $user = $becoming(new UserInput('', 'invalid-email', 10)); } catch (SemanticVariableException $e) { - // Three errors are collected simultaneously: + // Three errors collected simultaneously: // - EmptyNameException - // - InvalidEmailException + // - InvalidEmailException // - AgeTooYoungException - + $messages = $e->getErrors()->getMessages('en'); // ["Name cannot be empty", "Invalid email format", "Age must be at least 13"] } ``` -Rather than "stop at first error", you can **understand all problems at once**. +Rather than "fail fast"—**understand all problems at once**. -## Metamorphosis Including Errors +## Errors as Existence -Error states can also be treated as valid metamorphosis results: +Error states can be treated as valid metamorphosis results: ```php #[Be([ValidUser::class, InvalidUser::class])] final readonly class UserValidation { public ValidUser|InvalidUser $being; - + public function __construct(#[Input] string $data) { try { @@ -135,10 +132,8 @@ final readonly class UserValidation } ``` -Errors can be expressed as types rather than stopping execution with exceptions. - -Semantic exceptions make failure reasons clear, enabling users to understand specific correction methods. Error handling changes from problem reporting to **guidance toward problem resolution**. +Rather than halting execution with exceptions, errors are expressed as types. Failure, like success, is a legitimate result of transformation. --- -Every transformation is recorded as a story, as [Semantic Logging](./10-semantic-logging.html) ➡️ +For the full picture, see [Reference](./11-reference-resources.html) ➡️ diff --git a/manuals/1.0/ja/06-semantic-variables.md b/manuals/1.0/ja/06-semantic-variables.md index 5c1c2a5..7616fc8 100644 --- a/manuals/1.0/ja/06-semantic-variables.md +++ b/manuals/1.0/ja/06-semantic-variables.md @@ -150,40 +150,8 @@ public function __construct( フォーマットから値の範囲、さらにビジネスルールまで——名前が存在の条件を定義します。 -## 失敗の意味 - -存在が失敗したとき、その理由は意味を持たなければなりません: - -```php -#[Message([ - 'en' => '{email} is not a valid email address.', - 'ja' => '{email}は有効なメールアドレスではありません。' -])] -final readonly class InvalidEmailException extends DomainException -{ - public function __construct(public readonly string $email) {} -} -``` - -フレームワークは最初の例外で止まるのではなく、**すべての検証エラー**を収集します: - -```php -try { - $becoming(new UserRegistrationInput( - name: '', // EmptyNameException - email: 'invalid', // InvalidEmailException - age: -1 // InvalidAgeException - )); -} catch (SemanticVariableException $e) { - $e->getErrors()->getMessages('ja'); - // ['名前は空にできません。', '無効なメールアドレスです。', '無効な年齢です。'] -} -``` - -なぜ存在できないかの完全な理由が、ユーザーの言語で明らかになります。 - -日本には「言霊」という概念があります。言葉には現実を定義する力が宿るという思想です。意味変数はまさにそれです——名前に込められた意味が、システム全体の整合性を支えます。 +名前に宿る制約が守られないとき、存在は失敗します。その扱い方は[意味例外](./09-error-handling.html)で学びます。 --- -オブジェクト自身が次の変容先を知っています。その仕組み、[型駆動変容](./07-type-driven-metamorphosis.html)へ ➡️ +存在する理由のない存在はありません。[存在理由層](./08-reason-layer.html)へ ➡️ diff --git a/manuals/1.0/ja/09-error-handling.md b/manuals/1.0/ja/09-error-handling.md index c3e36d2..ba06483 100644 --- a/manuals/1.0/ja/09-error-handling.md +++ b/manuals/1.0/ja/09-error-handling.md @@ -1,60 +1,48 @@ --- layout: docs-ja -title: "9. エラーハンドリング" +title: "9. 意味例外" category: Manual permalink: /manuals/1.0/ja/09-error-handling.html --- -# エラーハンドリング & 検証 +# 意味例外 > 「過ちて改めざる、これを過ちという」 > >   —孔子『論語』(紀元前551-479年) -## 過ちの意味 +## 意味のある失敗 -Beフレームワークにおけるエラーハンドリングは例外をキャッチすることだけではありません—**存在が失敗したときに意味を保持する**ことです。 - -## 汎用的例外を超えて - -従来のエラーハンドリングは意味を失います: +汎用例外は**何が起きたか**を伝えます: ```php -try { - $user = new User($name, $email, $age); -} catch (Exception $e) { - // 何が間違っていたのか?なぜ?どう修正するのか? +catch (Exception $e) { echo $e->getMessage(); // "検証に失敗しました" } ``` -## 意味的例外: 失敗における意味 - -すべての失敗は**特定の存在論的意味**を持ちます: +それに対して意味例外は**なぜ存在できないか**を伝えます: ```php -try { - $user = $becoming(new UserInput($name, $email, $age)); -} catch (SemanticVariableException $e) { +catch (SemanticVariableException $e) { foreach ($e->getErrors()->exceptions as $exception) { echo get_class($exception) . ": " . $exception->getMessage(); - // EmptyNameException: 名前は空にできません。 - // InvalidEmailFormatException: メール形式が無効です。 - // AgeTooYoungException: 年齢は最低13歳でなければなりません。 + // EmptyNameException: 名前は空にできません + // InvalidEmailException: メール形式が無効です } } ``` -## 例外階層 +## ドメイン例外クラス -ドメイン例外は意味のあるカテゴリーを形成します: +すべての例外は`DomainException`を継承します。技術的例外(`RuntimeException`、`InvalidArgumentException`等)は使いません。失敗は常に**ドメインの意味を持つ失敗**として表現されます: ```php abstract class DomainException extends Exception {} final readonly class EmptyNameException extends DomainException {} -final readonly class InvalidEmailFormatException extends DomainException +final readonly class InvalidEmailException extends DomainException { public function __construct(public string $invalidEmail) { @@ -68,9 +56,22 @@ final readonly class NegativeAgeException extends AgeException {} final readonly class AgeTooHighException extends AgeException {} ``` -## 多言語エラーメッセージ +ドメイン例外はメッセージだけでなく**構造化データ**を持ちます。`$invalidEmail`プロパティから、プログラムは無効なメールアドレスの値にアクセスできます——表示、APIレスポンス、ログなど、さまざまな用途に: + +```php +catch (InvalidEmailException $e) { + $logData = [ + 'invalid_email' => $e->invalidEmail, // プログラムからアクセス可能 + 'user_ip' => $request->getClientIp(), + 'timestamp' => now() + ]; + Logger::warning('Invalid email attempt', $logData); +} +``` + +## 多言語メッセージ -意味的例外はユーザーの言語で話します: +`#[Message]`属性で、例外はユーザーの言語で話します: ```php #[Message([ @@ -81,56 +82,49 @@ final readonly class AgeTooHighException extends AgeException {} final readonly class EmptyNameException extends DomainException {} #[Message([ - 'en' => 'Age must be between {min} and {max} years.', - 'ja' => '年齢は{min}歳から{max}歳の間でなければなりません。' + 'en' => 'Age must be at least {min} years.', + 'ja' => '年齢は最低{min}歳でなければなりません。' ])] -final readonly class AgeOutOfRangeException extends DomainException +final readonly class AgeTooYoungException extends DomainException { - public function __construct( - public int $age, - public int $min = 0, - public int $max = 150 - ) {} + public function __construct(public int $min = 13) {} } ``` -## 自動エラー収集 +## エラー収集 -フレームワークは投げる前に**すべての検証失敗**を収集します: +フレームワークは最初のエラーで止まらず、**すべての検証エラー**を収集します: ```php -final readonly class UserValidation -{ - public function __construct( - #[Input] string $name, // EmptyNameExceptionを投げる可能性 - #[Input] string $email, // InvalidEmailFormatExceptionを投げる可能性 - #[Input] int $age // NegativeAgeExceptionを投げる可能性 - ) { - // いずれかの検証が失敗すると、すべてのエラーが収集される - // 単一のSemanticVariableExceptionがすべてを含む - } +try { + $user = $becoming(new UserInput('', 'invalid-email', 10)); +} catch (SemanticVariableException $e) { + // 3つのエラーが同時に収集される: + // - EmptyNameException + // - InvalidEmailException + // - AgeTooYoungException + + $messages = $e->getErrors()->getMessages('ja'); + // ["名前は空にできません", "メール形式が無効です", "年齢は最低13歳でなければなりません"] } ``` -「即座に失敗」ではなく—**完全な理解と共に完全に失敗**。 +「即座に失敗」ではなく——**すべての問題を一度に理解**。 -## エラー回復パターン +## エラーも存在の1つ -エラーは独自の権利における**有効な存在**になります: +エラー状態も変容の有効な結果として扱えます: ```php #[Be([ValidUser::class, InvalidUser::class])] final readonly class UserValidation { public ValidUser|InvalidUser $being; - - public function __construct( - #[Input] string $name, - #[Input] string $email, - #[Input] int $age - ) { + + public function __construct(#[Input] string $data) + { try { - $this->being = new ValidUser($name, $email, $age); + $this->being = new ValidUser($data); } catch (ValidationException $e) { $this->being = new InvalidUser($e->getErrors()); } @@ -138,62 +132,8 @@ final readonly class UserValidation } ``` -## 意味ログ統合 - -検証失敗は文脈と共に自動的にログされます: - -```php -{ - "event": "metamorphosis_failed", - "source_class": "UserInput", - "destination_class": "UserProfile", - "errors": [ - { - "exception": "EmptyNameException", - "message": "名前は空にできません", - "field": "name", - "value": "" - } - ] -} -``` - -## 開発 vs プロダクション - -```php -// 開発: 詳細なエラー詳細 -if (app()->environment('local')) { - $errors->getDetailedMessages(); -} - -// プロダクション: ユーザーフレンドリーなメッセージ -$errors->getMessages('ja'); -// ["名前は空にできません。", "メール形式が無効です。"] -``` - -## エラー条件のテスト - -```php -public function testCollectsAllValidationErrors(): void -{ - try { - $becoming(new UserInput('', 'invalid-email', -5)); - $this->fail('SemanticVariableExceptionが予期されました'); - } catch (SemanticVariableException $e) { - $errors = $e->getErrors(); - $this->assertCount(3, $errors->exceptions); - } -} -``` - -## 革命 - -意味的例外はエラーハンドリングを**問題報告**から**意味保持**に変換します。 - -存在が失敗したとき、理由は**明確で、実行可能で、多言語**になります。 - -エラーは障害ではありません—それらは成功した変容へとユーザーを導く**有効な存在**です。 +例外で実行を止めるのではなく、エラーを型として表現する。失敗も成功と同じく、変容の正当な結果です。 --- -すべての変容はストーリー、[意味的ログ](./10-semantic-logging.html)として記録されます ➡️ +フレームワークの全体像は[リファレンス](./11-reference-resources.html)へ ➡️ From eece0cf53d67233531d46e410b2efb2b29ff47fa Mon Sep 17 00:00:00 2001 From: Akihito Koriyama Date: Thu, 19 Mar 2026 22:19:11 +0900 Subject: [PATCH 06/16] Remove unimplemented chapters from menu - Change category to Draft for ch10 (Semantic Logging) and ch13 (LDD) - Remove from index pages - Update ch9 footer link to point to ch11 (Reference) --- manuals/1.0/en/10-semantic-logging.md | 2 +- manuals/1.0/en/13-vision-ldd.md | 2 +- manuals/1.0/en/index.md | 8 +------- manuals/1.0/ja/10-semantic-logging.md | 2 +- manuals/1.0/ja/13-vision-ldd.md | 2 +- manuals/1.0/ja/index.md | 8 +------- 6 files changed, 6 insertions(+), 18 deletions(-) diff --git a/manuals/1.0/en/10-semantic-logging.md b/manuals/1.0/en/10-semantic-logging.md index a3419b2..28a695c 100644 --- a/manuals/1.0/en/10-semantic-logging.md +++ b/manuals/1.0/en/10-semantic-logging.md @@ -1,7 +1,7 @@ --- layout: docs-en title: "10. Semantic Logging" -category: Manual +category: Draft permalink: /manuals/1.0/en/10-semantic-logging.html --- diff --git a/manuals/1.0/en/13-vision-ldd.md b/manuals/1.0/en/13-vision-ldd.md index 1f64922..69c2505 100644 --- a/manuals/1.0/en/13-vision-ldd.md +++ b/manuals/1.0/en/13-vision-ldd.md @@ -1,7 +1,7 @@ --- layout: docs-en title: "13. Log-Driven Development" -category: Manual +category: Draft permalink: /manuals/1.0/en/13-vision-ldd.html --- diff --git a/manuals/1.0/en/index.md b/manuals/1.0/en/index.md index feb49af..60edcfd 100644 --- a/manuals/1.0/en/index.md +++ b/manuals/1.0/en/index.md @@ -27,18 +27,12 @@ Inseparability of time and domain, self-determination of destiny ## [6. Semantic Variables](./06-semantic-variables.html) Domain-specific validation and ontological type safety -## [7. Type-Driven Metamorphosis](./07-type-driven-metamorphosis.html) -Self-determining objects with union types and the Being Property - ## [8. Reason Layer](./08-reason-layer.html) Raison d'être and the reasons that enable object existence -## [9. Error Handling & Validation](./09-error-handling.html) +## [9. Semantic Exceptions](./09-error-handling.html) Semantic exceptions and multilingual error messages -## [10. Semantic Logging](./10-semantic-logging.html) -Structured recording and audit trails of object metamorphosis - ## [11. Reference](./11-reference-resources.html) Essential resources and links for framework development diff --git a/manuals/1.0/ja/10-semantic-logging.md b/manuals/1.0/ja/10-semantic-logging.md index c8549a4..afabfeb 100644 --- a/manuals/1.0/ja/10-semantic-logging.md +++ b/manuals/1.0/ja/10-semantic-logging.md @@ -1,7 +1,7 @@ --- layout: docs-ja title: "10. 意味的ログ" -category: Manual +category: Draft permalink: /manuals/1.0/ja/10-semantic-logging.html --- diff --git a/manuals/1.0/ja/13-vision-ldd.md b/manuals/1.0/ja/13-vision-ldd.md index b70650d..65d078c 100644 --- a/manuals/1.0/ja/13-vision-ldd.md +++ b/manuals/1.0/ja/13-vision-ldd.md @@ -1,7 +1,7 @@ --- layout: docs-ja title: "13. ログ駆動開発" -category: Manual +category: Draft permalink: /manuals/1.0/ja/13-vision-ldd.html --- diff --git a/manuals/1.0/ja/index.md b/manuals/1.0/ja/index.md index 5d4fb29..3952d68 100644 --- a/manuals/1.0/ja/index.md +++ b/manuals/1.0/ja/index.md @@ -26,18 +26,12 @@ permalink: /manuals/1.0/ja/ ## [6. 意味変数](./06-semantic-variables.html) ドメイン固有の検証と存在論的型安全性 -## [7. 型駆動変容](./07-type-driven-metamorphosis.html) -ユニオン型と存在プロパティによる自己決定オブジェクト - ## [8. 存在理由層](./08-reason-layer.html) オブジェクトの存在を可能にする理由と存在根拠 -## [9. エラーハンドリング & 検証](./09-error-handling.html) +## [9. 意味例外](./09-error-handling.html) 意味的例外と多言語エラーメッセージ -## [10. 意味的ログ](./10-semantic-logging.html) -オブジェクト変容の構造化記録と監査証跡 - ## [11. リファレンス](./11-reference-resources.html) フレームワーク開発に必要なリソースとリンク集 From 46ba65e9fe0cbbd0caaf787fe74d13df94d93e59 Mon Sep 17 00:00:00 2001 From: Akihito Koriyama Date: Thu, 19 Mar 2026 22:19:18 +0900 Subject: [PATCH 07/16] Refactor chapter 11 (Reference) ja/en - Fix epigraph attribution: Laozi -> Wang Yangming (Chuanxi Lu) - Simplify structure: remove redundant headings and bold links - Unify ja/en structure --- manuals/1.0/en/11-reference-resources.md | 29 +++++++----------------- manuals/1.0/ja/11-reference-resources.md | 29 +++++++----------------- 2 files changed, 16 insertions(+), 42 deletions(-) diff --git a/manuals/1.0/en/11-reference-resources.md b/manuals/1.0/en/11-reference-resources.md index 8269b55..130dd76 100644 --- a/manuals/1.0/en/11-reference-resources.md +++ b/manuals/1.0/en/11-reference-resources.md @@ -7,30 +7,17 @@ permalink: /manuals/1.0/en/11-reference-resources.html # Reference -> "Knowledge is only completed through practice" -> -> —Lao Tzu, Tao Te Ching, Chapter 41 - -Essential resources and links for Be Framework project development. +> "Knowledge is the beginning of action, and action is the completion of knowledge" +> +>   —Wang Yangming, *Chuánxí Lù* (1518) ## Official Repositories -- **Be Framework Core**: [https://github.com/koriym/be-framework](https://github.com/koriym/be-framework) - Framework core and libraries - -- **Application Skeleton**: [https://github.com/be-framework/app](https://github.com/be-framework/app) - Project starter application skeleton - -- **Concept Stage Documentation**: [https://github.com/koriym/be-framework/blob/manual/concept/docs/README.md](https://github.com/koriym/be-framework/blob/manual/concept/docs/README.md) - Early documentation exploring framework design philosophy evolution +- [Be Framework Core](https://github.com/koriym/be-framework) — Framework core and libraries +- [Application Skeleton](https://github.com/be-framework/app) — Project starter skeleton +- [Concept Stage Documentation](https://github.com/koriym/be-framework/blob/manual/concept/docs/README.md) — Early documentation exploring design philosophy evolution ## Development Reference -### Naming Conventions -Naming standards for project development: -- [**Be Framework Naming Standards**](./convention/naming-standards.html) - Being-oriented naming principles - -### Theoretical Background -Be Framework's philosophical foundations: -- [**The Philosophy Behind**](./12-philosophy-behind.html) - Wu Wei, ontological programming, and philosophical roots - +- [Naming Standards](./convention/naming-standards.html) — Being-oriented naming principles +- [Philosophy Behind](./12-philosophy-behind.html) — Philosophical roots of ontological programming diff --git a/manuals/1.0/ja/11-reference-resources.md b/manuals/1.0/ja/11-reference-resources.md index 8754d08..cd4e9c7 100644 --- a/manuals/1.0/ja/11-reference-resources.md +++ b/manuals/1.0/ja/11-reference-resources.md @@ -7,30 +7,17 @@ permalink: /manuals/1.0/ja/11-reference-resources.html # リファレンス -> 「知識は実践を通してのみ完成する」 -> ->   —老子『道徳経』第41章 - -Be Frameworkでのプロジェクト開発に必要なリソースとリンク集です。 +> 「知は行の始なり、行は知の成るなり」 +> +>   —王陽明『伝習録』(1518年) ## 公式リポジトリ -- **Be Framework Core**: [https://github.com/koriym/be-framework](https://github.com/koriym/be-framework) - フレームワーク本体とコアライブラリ - -- **Application Skeleton**: [https://github.com/be-framework/app](https://github.com/be-framework/app) - プロジェクト開始用のアプリケーションスケルトン - -- **コンセプト段階ドキュメント**: [https://github.com/koriym/be-framework/tree/manual/docs-ja](https://github.com/koriym/be-framework/tree/manual/docs-ja) - フレームワークの設計思想の変遷を辿るための初期ドキュメント群 +- [Be Framework Core](https://github.com/koriym/be-framework) — フレームワーク本体 +- [Application Skeleton](https://github.com/be-framework/app) — プロジェクト開始用スケルトン +- [コンセプト段階ドキュメント](https://github.com/koriym/be-framework/tree/manual/docs-ja) — 設計思想の変遷を辿る初期ドキュメント群 ## 開発リファレンス -### 命名規約 -プロジェクト開発時の命名標準: -- [**Be Framework命名規約**](./convention/naming-standards.html) - 存在指向の命名原則 - -### 理論的背景 -Be Frameworkの哲学的基盤について: -- [**背後にある哲学**](./12-philosophy-behind.html) - 老子の無為、存在論的プログラミングの思想的ルーツ - +- [命名規約](./convention/naming-standards.html) — 存在指向の命名原則 +- [背後にある哲学](./12-philosophy-behind.html) — 存在論的プログラミングの思想的ルーツ From 9a5e0975f811ccc5ff657acd78c15391198328c6 Mon Sep 17 00:00:00 2001 From: Akihito Koriyama Date: Thu, 19 Mar 2026 22:19:27 +0900 Subject: [PATCH 08/16] Refactor chapter 12 (Philosophy Behind) ja/en MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rewrite intro: Being is Everything premise, domain questions lead to existence - Remove AI Collaboration section (unimplemented #[Accept]) - Remove Immanence/Transcendence section (covered in ch2-4) - Remove verbose ending (Where to Go, Conclusion) - Add Momentariness (kṣaṇa-vāda) to Buddhism section - Update connections table to match slide (add Husserl, Zhuangzi, Heidegger) - Rename section to Resonance, end with table - Fix UserProfile -> ValidatedUser - Reduce from 410 to 297 lines --- manuals/1.0/en/12-philosophy-behind.md | 171 +++++------------------- manuals/1.0/ja/12-philosophy-behind.md | 175 +++++-------------------- 2 files changed, 61 insertions(+), 285 deletions(-) diff --git a/manuals/1.0/en/12-philosophy-behind.md b/manuals/1.0/en/12-philosophy-behind.md index 518bf58..e733e6c 100644 --- a/manuals/1.0/en/12-philosophy-behind.md +++ b/manuals/1.0/en/12-philosophy-behind.md @@ -10,11 +10,13 @@ permalink: /manuals/1.0/en/12-philosophy-behind.html > "Everything flows" (Panta Rhei) > —Heraclitus (535-475 BC) -## Why Read This? +## Everything is Existence -You've learned how Be Framework works. This chapter explores **why** it works this way—the philosophical ideas that shaped its design. +Be—Being is Everything. This framework is built on the premise that everything is existence. -These connections between ancient philosophy and modern code aren't meant to impress. They're offered because understanding them may help you see familiar problems differently, and perhaps find the patterns more intuitive. +As we deepened our questions about domains, we arrived at questions of existence. What makes existence possible? How does existence transform? What does it mean to not exist? + +For 2,500 years, Eastern thinkers and Western philosophers have deepened their questions about existence. Yet this framework did not adopt philosophy as design principles. Rather, by deepening questions about domains, their teachings came to feel like testimony. --- @@ -51,17 +53,7 @@ One way to see Be Framework: an attempt to move closer to that original vision ## 2. The Question of "WHETHER?" -### Three Questions - -| Question | Focus | Paradigm | -|--------------|----------------|-------------| -| **HOW?** | Implementation | Imperative | -| **WHAT?** | Transformation | Functional | -| **WHETHER?** | Existence | Ontological | - -Traditional programming asks "How to validate?" or "What to transform?" - -Ontological Programming suggests asking first: "Can this exist at all?" +Procedural programming asks HOW?—how to do it. OOP asks WHAT?—what is it. Ontological programming asks first, WHETHER?—can it even exist. ```php #[Be(ValidatedUser::class)] @@ -248,40 +240,25 @@ final readonly class Child - `#[Input]` — what carries forward - `#[Inject]` — what enables transformation but doesn't persist ---- - -## 8. Immanence and Transcendence - -### Becoming Through Encounter +### Momentariness -Spinoza saw reality as interplay between what something already is (immanence) and what comes from beyond (transcendence). +Buddhism has another teaching: kṣaṇa-vāda, momentariness. Every existence lasts only an instant, then immediately ceases. ```php -final readonly class UserProfile -{ - public function __construct( - #[Input] string $name, // What it already has - #[Input] string $email, // Given nature - #[Inject] Formatter $formatter, // External capability - #[Inject] Validator $validator // World's contribution - ) { - $this->displayName = $formatter->format($name); - $this->isValid = $validator->validate($email); - } -} +$final = $becoming(new OrderInput($items, $customer, $payment)); +// OrderInput is born and immediately ceases +// ValidOrder is born, and it too ceases +// InStockOrder is born, and it too ceases +// ...only the final object remains ``` -The pattern: **Given nature** + **External capability** → **New state** - -This resembles how people develop—not through internal properties alone, but through encounters with others, culture, and environment. +From a distance, a flow of transformation. Up close, a series of cessation and arising. Each object exists for only a moment, passes forward to the next, and vanishes. What has transformed does not return to what it was before. --- -## 9. Three Kinds of Transparency - -Be Framework aims for clarity at three levels: +## 8. Two Kinds of Transparency -### 1. Structural +### Structural ```php UserInput → ValidatedUser → SavedUser → ActiveUser @@ -289,7 +266,7 @@ UserInput → ValidatedUser → SavedUser → ActiveUser The transformation path is visible in the types. -### 2. Semantic +### Semantic ```php string $email // Name suggests Email validation @@ -298,112 +275,24 @@ string $password // Name suggests Password validation Names carry meaning. -### 3. Execution - -```json -{ - "metamorphosis": "UserInput → ValidatedUser", - "inputs": { "email": "user@example.com" }, - "validations": ["email.format: passed"], - "result": "ValidatedUser created" -} -``` - -Logs record what happened. - -When these align, the code can serve as its own documentation. - ---- - -## 10. AI Collaboration - -Some decisions don't fit deterministic rules well. The `#[Accept]` pattern acknowledges this: - -```php -#[Be(DiagnosedPatient::class)] -final readonly class PatientSymptoms -{ - public Diagnosis|Undetermined $being; - - public function __construct( - #[Input] array $symptoms, - #[Accept] DiagnosticAI $ai - ) { - $result = $ai->analyze($symptoms); - $this->being = $result->confidence > 0.85 - ? new Diagnosis($result) - : new Undetermined($symptoms, $result->suggestions); - } -} -``` - -This suggests a division of concerns: - -- Humans define what states can exist and what they mean -- AI can help determine which state applies - ---- - -## 11. Connections - -These philosophical ideas share common themes: - -| Source | Concept | Expression in BOP | -|------------|-------------------------|--------------------------| -| Heraclitus | Flow | `Input → Being → Final` | -| Aristotle | Potentiality | `Success|Failure $being` | -| Sartre | Existence precedes essence | Type determines capability | -| Laozi | Non-forcing | `#[Be]` declaration | -| Buddhism | Interdependence | `#[Input]` + `#[Inject]` | -| Spinoza | Immanence/Transcendence | Input/Inject distinction | -| Leibniz | Sufficient reason | Reason Layer* | - -*See [Chapter 8: Reason Layer](./08-reason-layer.html) for details.* - -These aren't forced mappings—the patterns emerged and the philosophical parallels became apparent afterward. +When both structure and semantics are transparent, code serves as its own documentation. --- -## 12. Shifting Perspective - -### Different Questions - -| Era | Typical Question | -|-------------|--------------------------------| -| Assembly | "How to instruct the machine?" | -| Procedural | "What steps to execute?" | -| OOP | "Who is responsible?" | -| Functional | "What becomes what?" | -| Ontological | "What can exist?" | - -### A Different Role - -This framing suggests the programmer's work includes: - -- Deciding what states are meaningful -- Defining what existence is possible -- Designing the structure of valid states - ---- - -## Where to Go from Here - -To explore further: - -1. **Re-read earlier chapters** — the patterns may look different now -2. **Notice your habits** — when do you control vs. enable? -3. **Experiment** — try asking "What should this become?" instead of "What should this do?" - ---- - -## Conclusion - -Be Framework draws on old ideas: flow, potentiality, interdependence, natural transformation. These aren't decorations—they shaped the design. +## 9. Resonance -Whether these philosophical connections resonate with you or not, the practical patterns remain: immutable objects, type-driven transformation, constructor-based metamorphosis. +These philosophies resonate with Be Framework. -Ancient philosophers and modern programmers ask similar questions in different languages. A different paradigm offers a different way to see. And how we see shapes what we can build. +| Source | Concept | Expression in Be | +|---|---|---| +| Heraclitus | Everything flows | `Input → Being → Final` | +| Aristotle | Potentiality | `Success\|Failure $being` | +| Laozi | Non-forcing | `#[Be]` declaration | +| Spinoza | Necessary existence | Semantic variables | +| Husserl | Transcendence in immanence | `#[Input]` + `#[Inject]` | +| Zhuangzi | Self-testimony | `$been` | +| Heidegger | Language is the house of Being | Class names construct the world | +| Buddhism | Momentariness | Cessation and arising | --- -*Next: Return to [Overview](./01-overview.html) or see [Reference](./11-reference-resources.html) for additional resources.* diff --git a/manuals/1.0/ja/12-philosophy-behind.md b/manuals/1.0/ja/12-philosophy-behind.md index 3b42ab3..e51a6f0 100644 --- a/manuals/1.0/ja/12-philosophy-behind.md +++ b/manuals/1.0/ja/12-philosophy-behind.md @@ -10,11 +10,13 @@ permalink: /manuals/1.0/ja/12-philosophy-behind.html > 「万物は流転する」(パンタ・レイ) > ——ヘラクレイトス(紀元前535-475年) -## なぜこの章を読むのか +## すべては存在である -Beフレームワークの使い方は学びました。この章では、**なぜ**このように設計されたのか——その背後にある哲学的なアイデアを探ります。 +Be——Being is Everything。このフレームワークは「すべては存在である」という前提のもとに作られています。 -古代哲学と現代のコードを結びつけるのは、格好つけるためではありません。これらを理解することで、馴染みのある問題を違う角度から見られるようになり、パターンがより直感的に感じられるかもしれない——そう思って紹介しています。 +ドメインに対する問いを深めていったとき、私たちは存在の問いにたどり着きました。何が存在を可能にするのか。存在はどのように変容するのか。存在しないとはどういうことか。 + +2500年にわたり、東洋の思想家も西洋の哲学者も存在に対する問いを深めてきました。しかしこのフレームワークは哲学を設計原則として採用したのではありません。ドメインへの問いを深めた結果、それらの教えが証言のように感じられたのです。 --- @@ -51,17 +53,7 @@ Beフレームワークの一つの見方:オブジェクトが自らの変容 ## 2.「WHETHER?」という問い -### 三つの問い - -| 問い | 焦点 | パラダイム | -|------|------|------------| -| **HOW?** | 実装 | 命令型 | -| **WHAT?** | 変換 | 関数型 | -| **WHETHER?** | 存在 | 存在論的 | - -従来のプログラミングは「どう検証するか?」「何に変換するか?」と問いました。 - -存在論的プログラミングは、まず「そもそも存在できるか?」と問います。 +手続き型はHOW?——どうやるか。OOPはWHAT?——それは何か。存在論的プログラミングはまず、WHETHER?——そもそも存在できるか、と問います。 ```php #[Be(ValidatedUser::class)] @@ -205,7 +197,7 @@ $user = $becoming(new UserInput($data)); --- -## 7. 仏教の縁起 +## 7. 仏教 ### 縁起(プラティーティヤサムトパーダ) @@ -248,40 +240,25 @@ final readonly class Child - `#[Input]` — 引き継がれるもの - `#[Inject]` — 変容を可能にするが持続しないもの ---- - -## 8. 内在と超越 +### 刹那滅 -### 出会いを通じた生成 - -スピノザは現実を、すでにそうであるもの(内在)と外から来るもの(超越)の相互作用として捉えました。 +仏教にはもうひとつ、刹那滅(クシャナ・ヴァーダ)という教えがあります。すべての存在は一瞬だけ存在し、即座に消滅する。 ```php -final readonly class UserProfile -{ - public function __construct( - #[Input] string $name, // すでに持っているもの - #[Input] string $email, // 与えられた性質 - #[Inject] Formatter $formatter, // 外部の能力 - #[Inject] Validator $validator // 世界からの寄与 - ) { - $this->displayName = $formatter->format($name); - $this->isValid = $validator->validate($email); - } -} +$final = $becoming(new OrderInput($items, $customer, $payment)); +// OrderInputは生まれた瞬間に消える +// ValidOrderが生まれ、それも消える +// InStockOrderが生まれ、それも消える +// ...最終オブジェクトだけが残る ``` -パターン:**与えられた性質** + **外部の能力** → **新しい状態** - -これは人間の発達に似ています——内部の性質だけでなく、他者、文化、環境との出会いを通じて。 +遠くから見れば変容の流れ。近くで見れば、消滅と生成の繰り返し。各オブジェクトは一瞬だけ存在し、次の存在に引き継いで消えます。変容したものは変容前に戻りません。 --- -## 9. 三種類の透明性 - -Beフレームワークは三つのレベルでの明確さを目指しています: +## 8. 二種類の透明性 -### 1. 構造的 +### 構造的 ```php UserInput → ValidatedUser → SavedUser → ActiveUser @@ -289,7 +266,7 @@ UserInput → ValidatedUser → SavedUser → ActiveUser 変容の経路が型に見えています。 -### 2. 意味的 +### 意味的 ```php string $email // 名前がEmail検証を示唆 @@ -298,112 +275,22 @@ string $password // 名前がPassword検証を示唆 名前が意味を運びます。 -### 3. 実行時 - -```json -{ - "metamorphosis": "UserInput → ValidatedUser", - "inputs": { "email": "user@example.com" }, - "validations": ["email.format: passed"], - "result": "ValidatedUser created" -} -``` - -ログが何が起きたかを記録します。 - -これらが揃うと、コードはそれ自身のドキュメントになります。 - ---- - -## 10. AIとの協働 - -決定論的なルールにうまく当てはまらない判断もあります。`#[Accept]`パターンはこれを認めています: - -```php -#[Be(DiagnosedPatient::class)] -final readonly class PatientSymptoms -{ - public Diagnosis|Undetermined $being; - - public function __construct( - #[Input] array $symptoms, - #[Accept] DiagnosticAI $ai - ) { - $result = $ai->analyze($symptoms); - $this->being = $result->confidence > 0.85 - ? new Diagnosis($result) - : new Undetermined($symptoms, $result->suggestions); - } -} -``` - -これは関心の分離を示唆しています: - -- 人間がどの状態が存在でき、何を意味するかを定義する -- AIがどの状態が適用されるか判断を助ける +構造と意味の両方で透明であることが、コードをそれ自身のドキュメントにします。 --- -## 11. 関連性 - -これらの哲学的アイデアは共通のテーマを持っています: - -| 出典 | 概念 | BOPでの表現 | -|------|------|-------------| -| ヘラクレイトス | 流転 | `Input → Being → Final` | -| アリストテレス | 可能態 | `Success|Failure $being` | -| サルトル | 実存は本質に先立つ | 型が能力を決定する | -| 老子 | 無為 | `#[Be]`宣言 | -| 仏教 | 縁起 | `#[Input]` + `#[Inject]` | -| スピノザ | 内在/超越 | Input/Injectの区別 | -| ライプニッツ | 充足理由 | 存在理由層* | - -*詳細は[第8章:存在理由層](./08-reason-layer.html)を参照。* - -これらは無理やりな対応づけではありません——パターンが先に生まれ、哲学的な類似性は後から明らかになりました。 - ---- - -## 12. 視点の転換 - -### 異なる問い - -| 時代 | 典型的な問い | -|------|--------------| -| アセンブリ | 「機械にどう指示するか?」 | -| 手続き型 | 「どのステップを実行するか?」 | -| OOP | 「誰が責任を持つか?」 | -| 関数型 | 「何が何になるか?」 | -| 存在論的 | 「何が存在できるか?」 | +## 9. 共鳴 -### 異なる役割 +これらの哲学が、Beフレームワークと共鳴しています。 -このフレーミングは、プログラマの仕事に以下が含まれることを示唆します: - -- どの状態が意味を持つか決める -- どの存在が可能か定義する -- 有効な状態の構造を設計する - ---- - -## ここからどこへ - -さらに探求するために: - -1. **前の章を読み返す** — パターンが違って見えるかもしれません -2. **自分の習慣に気づく** — いつ制御し、いつ可能にしているか? -3. **実験する** — 「これは何をすべきか?」の代わりに「これは何になるべきか?」と問うてみる - ---- - -## 結論 - -Beフレームワークは古いアイデアに基づいています:流転、可能態、縁起、自然な変容。これらは飾りではありません——設計を形作りました。 - -これらの哲学的な繋がりが響くかどうかは別として、実践的なパターンは残ります:イミュータブルなオブジェクト、型駆動の変容、コンストラクタベースの変容。 - -古代の哲学者と現代のプログラマは、異なる言語で似た問いを投げかけています。異なるパラダイムは、異なる見方を提供します。そして、どう見るかが、何を作れるかを形作るのです。 - ---- +| 出典 | 概念 | Beでの表現 | +|------|------|----------------------| +| ヘラクレイトス | 万物流転 | `Input → Being → Final` | +| アリストテレス | 可能態 | `Success\|Failure $being` | +| 老子 | 無為 | `#[Be]`宣言 | +| スピノザ | 必然的存在 | 意味変数 | +| フッサール | 内在における超越 | `#[Input]` + `#[Inject]` | +| 荘子 | 自己証明 | `$been` | +| ハイデガー | 言葉は存在の家 | クラス名が世界を構築 | +| 仏教 | 刹那滅 | 消滅と生成の繰り返し | -*次へ:[概要](./01-overview.html)に戻る、または[リファレンス](./11-reference-resources.html)で追加リソースを参照* From 7e9b492709e67453e1f47875ed2e58b31ce81151 Mon Sep 17 00:00:00 2001 From: Akihito Koriyama Date: Thu, 19 Mar 2026 22:19:33 +0900 Subject: [PATCH 09/16] Fix naming standards and Convention CSS - Add frontmatter to EN naming-standards (was missing layout/category) - Include github-markdown CSS for Convention category pages - Rewrite EN to match JA structure (remove BeingUser pattern) - Simplify Core Philosophy section - Remove verbose ending quote --- _includes/manuals/1.0/header.html | 2 +- manuals/1.0/en/convention/naming-standards.md | 283 +++++++----------- manuals/1.0/ja/convention/naming-standards.md | 14 +- 3 files changed, 112 insertions(+), 187 deletions(-) diff --git a/_includes/manuals/1.0/header.html b/_includes/manuals/1.0/header.html index 430ada4..60e5727 100644 --- a/_includes/manuals/1.0/header.html +++ b/_includes/manuals/1.0/header.html @@ -7,7 +7,7 @@ - {% if page.category == 'Manual' %} + {% if page.category == 'Manual' or page.category == 'Convention' %} {% endif %} diff --git a/manuals/1.0/en/convention/naming-standards.md b/manuals/1.0/en/convention/naming-standards.md index 195e062..6206fbf 100644 --- a/manuals/1.0/en/convention/naming-standards.md +++ b/manuals/1.0/en/convention/naming-standards.md @@ -1,3 +1,10 @@ +--- +layout: docs-en +title: "Be Framework Naming Standards" +category: Convention +permalink: /manuals/1.0/en/convention/naming-standards.html +--- + # Be Framework Naming Standards > Code as philosophy: names that reflect existence, not actions @@ -6,12 +13,7 @@ This document establishes naming conventions that align with Be Framework's onto ## Core Philosophy -**"Objects don't do things—they become what they are meant to be"** - -Our naming reflects this fundamental shift from imperative to existential thinking: -- From **action-oriented** names → **existence-oriented** names -- From **what it does** → **what it is** -- From **controlling** → **being** +Names express **what it is**, not **what it does**. ## Class Naming Patterns @@ -22,231 +24,166 @@ Our naming reflects this fundamental shift from imperative to existential thinki ```php // ✅ Correct final readonly class UserInput -final readonly class OrderInput +final readonly class OrderInput final readonly class DataInput final readonly class PaymentInput // ❌ Avoid final readonly class UserData // Too generic final readonly class CreateUserRequest // Action-oriented -final readonly class UserCommand // Imperative thinking +final readonly class UserDto // Technical-oriented ``` ### Being Classes -**Pattern**: `Being{Domain}` or `{Domain}Being` -**Purpose**: Intermediate transformation stages where objects discover their nature +**Pattern**: `{State}{Domain}` +**Purpose**: Intermediate transformation stages ```php -// ✅ Correct - Being prefix (recommended) -final readonly class BeingUser -final readonly class BeingOrder -final readonly class BeingData -final readonly class BeingPayment - -// ✅ Acceptable - Being suffix -final readonly class UserBeing -final readonly class OrderBeing +// ✅ Correct +final readonly class ValidatedUser +final readonly class AuthenticatedUser +final readonly class ProcessedOrder +final readonly class VerifiedPayment // ❌ Avoid -final readonly class UserValidator // Action-oriented -final readonly class OrderProcessor // What it does, not what it is -final readonly class DataTransformer // Imperative thinking +final readonly class UserValidator // Service-oriented +final readonly class OrderProcessor // Action-oriented ``` ### Final Objects -**Pattern**: Domain-specific result names expressing final state -**Purpose**: Complete transformed beings representing successful completion +**Pattern**: `{CompletedState}` +**Purpose**: The destination of metamorphosis ```php -// ✅ Correct - State of being -final readonly class ValidatedUser -final readonly class ProcessedOrder -final readonly class Success -final readonly class Failure -final readonly class ApprovedLoan -final readonly class RejectedApplication - -// ❌ Avoid -final readonly class UserResponse // Implementation detail -final readonly class OrderResult // Generic -final readonly class ProcessingOutput // Action-oriented +// ✅ Correct +final readonly class RegisteredUser +final readonly class CompletedOrder +final readonly class SuccessfulPayment +final readonly class PublishedArticle + +// ❌ Avoid +final readonly class UserEntity // Technical-oriented +final readonly class OrderResult // Result-oriented ``` ## Property Naming -### Being Property -**Pattern**: `public {Type1}|{Type2} $being;` -**Purpose**: Carries the object's destiny through union types +### Properties as Semantic Variables +Property names are automatically linked to the semantic variable system: ```php -// ✅ Correct -public Success|Failure $being; -public ValidUser|InvalidUser $being; -public ApprovedLoan|RejectedLoan $being; - -// ❌ Avoid -public mixed $result; // Not type-specific -public object $outcome; // Too generic -public array $data; // Action-oriented +// Property names automatically map to semantic variable classes +#[Input] string $emailAddress // → EmailAddress semantic variable +#[Input] string $userName // → UserName semantic variable +#[Input] int $age // → Age semantic variable ``` -### Immanent Properties -**Pattern**: Descriptive names reflecting inherent identity -**Purpose**: What the object already is +### Being Property +**Pattern**: `$being` +**Purpose**: Represents the object's next existential state ```php -// ✅ Correct -public string $email; -public Money $amount; -public UserId $userId; -public \DateTimeImmutable $timestamp; - -// ❌ Avoid -public string $inputEmail; // Redundant prefix -public Money $requestAmount; // Action-oriented +public SuccessfulPayment|FailedPayment $being; +public ActiveUser|SuspendedUser $being; ``` -## Parameter Naming +## Method Naming Principles -### Constructor Parameters -**Pattern**: Match property names for Immanent, descriptive for Transcendent +### Traditional methods do not exist in Be Framework ```php -// ✅ Correct -public function __construct( - #[Input] string $email, // Immanent - matches property - #[Input] Money $amount, // Immanent - matches property - #[Inject] EmailValidator $validator, // Transcendent - capability - #[Inject] PaymentGateway $gateway // Transcendent - external service -) {} - -// ❌ Avoid -public function __construct( - #[Input] string $userEmail, // Different from property name - #[Input] Money $inputAmount, // Redundant prefix - #[Inject] object $emailChecker, // Not descriptive - #[Inject] mixed $paymentService // Not type-specific -) {} +// ❌ Traditional OOP style (avoid) +class User { + public function validate() { } + public function save() { } + public function delete() { } +} + +// ✅ Be Framework style +final readonly class ValidatedUser { + public function __construct(UserInput $input) { + // Validation is executed as a precondition for existence + } +} ``` -## Attribute Usage +## Variable Naming -### Be Attribute -**Pattern**: `#[Be(DestinyClass::class)]` or `#[Be([Option1::class, Option2::class])]` +### Local Variables +Use names that reflect existential state: ```php -// ✅ Single destiny -#[Be(BeingUser::class)] -final readonly class UserInput - -// ✅ Multiple destinies -#[Be([ValidatedUser::class, InvalidUser::class])] -final readonly class BeingUser +// ✅ Correct +$validatedInput = new ValidatedUserInput($rawInput); +$authenticatedUser = new AuthenticatedUser($validatedInput); +$finalUser = $authenticatedUser->being; // ❌ Avoid -#[Be(UserProcessor::class)] // Action-oriented -#[Be(HandleUser::class)] // Imperative +$result = validateUser($input); // Action-oriented +$data = processInput($rawInput); // Too generic ``` -### Input/Inject Comments -**Pattern**: Always include philosophical comments +### Dependency Injection +**Pattern**: `{InterfaceName}` (no Service suffix) ```php -// ✅ Correct -public function __construct( - #[Input] string $email, // Immanent - #[Inject] EmailValidator $validator // Transcendent -) {} - -// ❌ Missing philosophy -public function __construct( - #[Input] string $email, - #[Inject] EmailValidator $validator -) {} +final readonly class AuthenticatedUser { + public function __construct( + #[Input] UserInput $input, + #[Inject] PasswordHasher $hasher, // ✅ As capability + #[Inject] UserRepository $repository // ✅ As repository + ) {} +} ``` -## Domain-Specific Examples +## File and Directory Structure -### E-commerce Domain -```php -// Input → Being → Final -ProductInput → BeingProduct → [ValidProduct, InvalidProduct] -OrderInput → BeingOrder → [ProcessedOrder, FailedOrder] -PaymentInput → BeingPayment → [SuccessfulPayment, DeclinedPayment] -``` +### Semantic Variables +**Location**: `src/Domain/SemanticVariable/` +**Naming**: Word combinations, PascalCase -### User Management Domain -```php -// Input → Being → Final -UserInput → BeingUser → [RegisteredUser, ConflictingUser] -LoginInput → BeingLogin → [AuthenticatedUser, FailedAuthentication] -ProfileInput → BeingProfile → [UpdatedProfile, InvalidProfile] +```txt +src/Domain/SemanticVariable/ +├── EmailAddress.php +├── UserName.php +├── ProductCode.php +└── PaymentAmount.php ``` -### Data Processing Domain -```php -// Input → Being → Final -DataInput → BeingData → [ProcessedData, CorruptedData] -FileInput → BeingFile → [ValidatedFile, InvalidFile] -ConfigInput → BeingConfig → [LoadedConfig, MalformedConfig] +### Domain Objects +**Location**: `src/Domain/` +**Naming**: Reflects existential state + +```txt +src/Domain/ +├── User/ +│ ├── UserInput.php +│ ├── ValidatedUser.php +│ └── RegisteredUser.php +└── Order/ + ├── OrderInput.php + ├── ProcessedOrder.php + └── CompletedOrder.php ``` -## Anti-Patterns to Avoid - -### Imperative Naming -```php -// ❌ Action-oriented -ProcessUser, ValidateOrder, TransformData -CreatePayment, HandleRequest, ExecuteCommand - -// ✅ Being-oriented -BeingUser, BeingOrder, BeingData -BeingPayment, BeingRequest, BeingCommand -``` +## Philosophical Naming Principles -### Generic Naming +### 1. Existence First ```php -// ❌ Too generic -Handler, Processor, Manager, Service, Util - -// ✅ Specific and meaningful -BeingUser, ValidatedOrder, ProcessedPayment +// Express existence, not action +final readonly class DeletedUser // ✅ Existence of deleted state +final readonly class UserDeleter // ❌ Action of deleting ``` -### Technical Implementation Details +### 2. Temporal Direction ```php -// ❌ Implementation-focused -UserDTO, OrderVO, PaymentPOJO, DataObject - -// ✅ Domain-focused -UserInput, BeingOrder, ProcessedPayment +// Express the natural flow of metamorphosis +$input → $validated → $authenticated → $registered ``` -## Naming Checklist - -Before naming any class, ask: - -1. **Existence Question**: "What does this object *be* rather than *do*?" -2. **Stage Question**: "What stage of metamorphosis does this represent?" -3. **Philosophy Question**: "Does this name reflect ontological thinking?" -4. **Clarity Question**: "Will developers understand the object's nature?" -5. **Consistency Question**: "Does this follow our established patterns?" - -## Evolution of Names - -As your understanding of the domain deepens, names may evolve: - +### 3. Semantic Completeness ```php -// Initial understanding -UserValidator → - -// Deeper understanding -BeingUser → - -// Full ontological clarity -BeingUser // with clear Immanent/Transcendent distinction +// Names carry constraints +string $emailAddress // Must be a valid email address +int $age // Negative values cannot exist ``` - ---- - -*"In Be Framework, names are not labels—they are declarations of existence. Choose them as carefully as you would choose words in poetry, for they shape how we think about the reality we create."* \ No newline at end of file diff --git a/manuals/1.0/ja/convention/naming-standards.md b/manuals/1.0/ja/convention/naming-standards.md index 9d750f5..3854b86 100644 --- a/manuals/1.0/ja/convention/naming-standards.md +++ b/manuals/1.0/ja/convention/naming-standards.md @@ -13,12 +13,7 @@ permalink: /manuals/1.0/ja/convention/naming-standards.html ## 核心哲学 -**「オブジェクトは物事をするのではない—あるべき姿になる」** - -私たちの命名は、命令的思考から存在論的思考への根本的転換を反映します: -- **行動指向**の名前 → **存在指向**の名前 -- **何をするか** → **何であるか** -- **制御する** → **存在する** +命名は**何をするか**ではなく**何であるか**を表現します。 ## クラス命名パターン @@ -193,10 +188,3 @@ string $emailAddress // 有効なメールアドレスでなければなら int $age // 負の値は存在できない ``` -## まとめ - -Be Frameworkの命名規約は単なるスタイルガイドではなく、存在論的プログラミングの哲学を体現します。名前を通じて、コードは**行う**ものから**存在する**ものへと変容し、より自然で理解しやすいソフトウェアが実現されます。 - ---- - -*「名前は単なるラベルではありません。存在の意味そのものです。」* \ No newline at end of file From 073fa058b5e5d9cc690d8c730281fef4d43f777e Mon Sep 17 00:00:00 2001 From: Akihito Koriyama Date: Thu, 19 Mar 2026 23:03:38 +0900 Subject: [PATCH 10/16] Refactor FAQ and Demos ja/en MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FAQ: Deepen Q3, Q9, Q11, Q16 with trilogy context, improve glossary, remove AI agent section and related chapter links section. Demos: Soften intro, fix terminology (変換→変容), add "Doing for Being" context to Final section. --- manuals/1.0/en/14-faq.md | 152 +++++++++++++++++++-------------------- manuals/1.0/en/demos.md | 12 ++-- manuals/1.0/ja/14-faq.md | 148 +++++++++++++++++--------------------- manuals/1.0/ja/demos.md | 12 ++-- 4 files changed, 152 insertions(+), 172 deletions(-) diff --git a/manuals/1.0/en/14-faq.md b/manuals/1.0/en/14-faq.md index 40d6778..3e4b6ba 100644 --- a/manuals/1.0/en/14-faq.md +++ b/manuals/1.0/en/14-faq.md @@ -7,8 +7,6 @@ permalink: /manuals/1.0/en/faq.html # Be Framework FAQ -> Last updated: 2025-09-13 - ## 0) TL;DR ### Q. Is this a new "programming paradigm"? @@ -23,22 +21,42 @@ While it's a significant paradigm shift philosophically, implementation-wise it ### Q1. How is this different from MVC or DDD? -A. MVC is a structural pattern for responsibility separation, DDD is a modeling methodology. +A. They operate at different layers and can coexist. + +Web MVC effectively functions as input/output responsibility separation, and DDD is a domain modeling methodology. Be Framework is a design paradigm that organizes object creation through "existence conditions and temporal transformation" — it can be called from an MVC Controller or used inside a DDD aggregate. + +Interestingly, what MVC originally aimed for — "projecting mental models" — and what DDD aimed for — "coding in business language" — are naturally realized in Be Framework through existence types and semantic variables. + +### Q1-a. How does this relate to CQRS? -Be Framework is a design paradigm centered on "existence conditions and temporal transformation," where flow self-organizes through `#[Be]` and `$being`. +A. The separation of "decision-making" and "data retrieval" that CQRS achieves through external structure is naturally inherent within a single existence type in Be. + +The constructor is decision-making (Command), and public properties are data retrieval (Query). Business decisions that tend to get buried in generic methods like `updateUser()` are expressed as type names like `DeactivatedUser`, so intent is never lost from the code. ### Q2. Is this OOP or FP? -A. It works with both. It emphasizes immutability and referential transparency while realizing one-time complete transformation in constructors (entelecheia) using OOP containers. +A. It incorporates elements of both, but the relationship with OOP is more fundamental. + +OOP originally envisioned a world where autonomous objects cooperate through messages. In practice, however, service layers issue instructions while objects become obedient data containers. In Be, objects declare their own destiny through `#[Be]` and self-organize without external orchestrators. This is a recovery of the autonomy that OOP originally intended. + +### Q2-a. How are FP elements utilized? + +A. Existence types are immutable once transformation is complete. + +Side effects are localized to the constructor, and completed objects can be referenced as pure data. With clear preconditions (`#[Input]`) and postconditions (public properties), each existence type can be tested independently, and results are always predictable. + +Public properties are considered taboo in traditional OOP, but in practice objects circulate as typed values, and in tests postconditions can be verified directly. (For concrete testing approaches, see [Q13](#q13-whats-the-testing-strategy).) ### Q3. What's the benefit of defining "BEING (what something is)" first? -A. It makes invalid states impossible to generate upfront. +A. Invalid states become inexpressible altogether. + +The defensive if statements scattered throughout traditional code are necessary because invalid states are representable as types. In Be, types are existence conditions themselves, so there are no types representing invalid states, and the guard statements disappear with them. Type = reachable state becomes the API specification directly. + +### Q4. What are "temporal existence types"? -Defensive if/guard statements are drastically reduced, and type = reachable state becomes API specification. +A. Types like `ValidatedUser`, `SavedUser`, `DeletedUser` express the "when" in progress. -### Q4. What are "temporal existence types"? -A. Types like `ValidatedUser`, `SavedUser`, `DeletedUser` express the "when" in progress. Time and domain are inseparable (details: [Metamorphosis](./05-metamorphosis.html)). --- @@ -51,7 +69,7 @@ A. It declares an object's destiny (what it will become next). You can specify single or multiple transformation candidates, and the framework automatically selects the continuation at runtime based on the type of the `$being` property. -For details, see [Type-Driven Metamorphosis](./07-type-driven-metamorphosis.html). +For details, see [Metamorphosis](./05-metamorphosis.html). ### Q6. What's the role of the `$being` property? @@ -111,9 +129,9 @@ function updateArticle(UserId $userId, AuthorId $authorId) { ### Q9. What is the "Reason Layer"? -A. It injects the foundation = tool set that enables a certain existence state as objects. +A. It gathers the foundation — the complete tool set — for an existence to come into being, into a single object. -It bundles related tools meaningfully from traditional individual DI, improving testability. +In traditional DI, dependencies are injected individually and scattered, making it hard to see "what are the preconditions for this existence?" Reason bundles the grounds for existence by meaning, so in tests you can swap out the entire set of preconditions at once. See [Reason Layer](./08-reason-layer.html) for details. @@ -131,19 +149,25 @@ See [Final Objects](./04-final-objects.html) for details. ### Q11. Where do side effects occur? -A. Principally completed by delegating to Reason within constructors. This eliminates the need for external orchestrators and huge service layers. +A. Inside the constructor, delegated to Reason and completed there. + +Traditional service layers operate on objects from the outside — "save this," "notify that." In Be, the object itself completes side effects in its constructor. This is the autonomy described in [Q2](#q2-is-this-oop-or-fp) in action — no external orchestrator needed. ### Q12. How are exceptions handled? A. Using semantic exceptions that hold failures as collections (supporting multilingual messages). "Partial success/partial failure" can also be expressed as valid existence of Invalid~. -See [Error Handling](./09-error-handling.html) for details. +See [Semantic Exceptions](./09-error-handling.html) for details. ### Q13. What's the testing strategy? -A. Verify each existence (type) individually. Preconditions = `#[Input]`, postconditions = `public` properties. Use cases can be kept sufficiently thin with `#[Be]` chain smoke tests. +A. Verify each existence (type) independently. + +As described in [Q2-a](#q2-a-how-are-fp-elements-utilized), preconditions (`#[Input]`) and postconditions (public properties) are explicit, making the test interface self-evident. No getters or reflection needed — assert public properties directly. -### Q15. When to choose "linear," "branching," or "nested"? +Use case-level tests can be kept sufficiently thin with `#[Be]` chain smoke tests. DI has costs, but localized side effects and reduced bugs make it a net positive. + +### Q14. When to choose "linear," "branching," or "nested"? A. Procedure-dependent = linear / Results exclusive by conditions = branching / Convergence of independent processes = nested. When in doubt, start with minimal linear. @@ -153,41 +177,45 @@ See [Implementation Guidelines](./05-metamorphosis.html) for details. ## 4) Integration with Existing Assets -### Q16. Can this be introduced to existing MVC apps? +### Q15. Can this be introduced to existing MVC apps? A. Yes. Replace the Use Case layer with Be, and just call `becoming(new …Input)` from Controllers. Gradually organize into immanent/transcendent. -### Q17. Where do you use DB or external APIs? +### Q16. Where do you use DB or external APIs? + +A. Confined to Reason. -A. In Reason. Storage and transmission means are consolidated in Reason, separated from existence (state) definition. +Persistence and external communication are implementation details, not user concerns. By consolidating them in Reason, existence types are freed from database schemas and API constraints — the definition of existence is separated from technical means. -### Q18. What are the framework dependencies? +### Q17. What are the framework dependencies? A. Core uses PHP standard + DI (e.g., Ray.Di). Integration with Laravel/Symfony etc. is possible via adapters. -### Q19. Do static analysis and IDE completion work? +### Q18. Do static analysis and IDE completion work? A. Very well since types are "states." Branching is made explicit with union types, and completion is safe too. --- -## 5) Operations, Logging & Auditing +## 5) Operations & Auditing -### Q20. How are logs recorded? +### Q19. How are logs recorded? -A. Semantic logging is recommended (Koriym.SemanticLogger integration). Record transformation (from/to/reason/evidence) as structured JSON. +A. Recording transformations (from/to/reason/evidence) as structured JSON is recommended. -See [Semantic Logging](./10-semantic-logging.html) for details. +The semantic logging mechanism is at the conceptual stage. -### Q21. How does audit compliance work? +### Q20. How does audit compliance work? -A. `$been` (self-proof) + semantic logging can provide complete audit trails. Personal information follows minimum privilege principles at the Reason layer. +A. `$been` (self-proof) provides the foundation for audit trails. + +Personal information follows minimum privilege principles at the Reason layer. --- -## 7) Migration +## 6) Migration -### Q24. What are the migration steps for existing code? (Minimal steps) +### Q21. What are the migration steps for existing code? (Minimal steps) A. 1. Choose one representative use case @@ -196,34 +224,31 @@ A. 4. Consolidate external dependencies into Reason 5. Call `becoming(new …Input)` from Controller 6. Migrate validation to semantic variables / replace exceptions semantically -7. Introduce semantic logging --- -## 8) Future Features +## 7) Future Features -### Q25. What about `#[Accept]` (Extended Decision Making)? +### Q22. What about `#[Accept]` (Extended Decision Making)? A. Conceptual stage. Plans to delegate undeterminable decisions to experts or AI, handling certainty and uncertainty in one framework. -See [Type-Driven Metamorphosis](./07-type-driven-metamorphosis.html) end note for details. - --- -## 9) Examples & Snippets +## 8) Examples & Snippets -### Q26. What's a minimal example of typical flow? +### Q23. What's a minimal example of typical flow? A. ```php // 1) Input (immanent only) -#[Be(UserProfile::class)] +#[Be(ValidatedUser::class)] final readonly class UserInput { public function __construct(public string $name, public string $email) {} } // 2) Being (moment of transformation) -final readonly class UserProfile { +final readonly class ValidatedUser { public function __construct( #[Input] string $name, #[Input] string $email, @@ -238,57 +263,28 @@ final readonly class UserProfile { } // 3) Execution (self-organization) -$profile = $becoming(new UserInput($name, $email)); +$user = $becoming(new UserInput($name, $email)); -// Result: UserProfile object -// $profile->display: "Formatted name" -// $profile->isValid: true (for valid email) +// Result: ValidatedUser object +// $user->display: "Formatted name" +// $user->isValid: true (for valid email) ``` --- -## 10) Detailed Term Explanations +## 9) Detailed Term Explanations ### Being-oriented / Ontological -A design philosophy that treats existence possibility and time as primary abstractions. It's a way of thinking that centers on "what can exist" rather than the traditional "what to do," understanding program states as temporal existence. +A design philosophy that centers on "what can exist" rather than "what to do." It treats existence possibility and time as primary abstractions, understanding program states as temporal existence. As a result, states that cannot exist are never represented as types, so invalid states are naturally eliminated. ### Immanence / Transcendence -Immanence refers to the intrinsic properties and information that an object naturally possesses. Transcendence refers to capabilities and information provided by the external environment or dependencies. In Be Framework, new existence emerges from the combination of these two. - -### Entelecheia -A concept derived from Aristotelian philosophy, representing the "moment of transformation" when potentiality moves to actuality. In Be Framework, it refers to the moment when immanence and transcendence meet in the constructor to complete a new existence. +Immanence (`#[Input]`) is the intrinsic properties an object possesses; transcendence (`#[Inject]`) is the power provided from outside. Transformation always follows the formula: immanence + transcendence → new immanence. Transcendence transforms the immanent and then vanishes. ### Reason Layer -An aggregation of the foundation and tool set necessary for establishing a certain existence state as objects. It enhances testability and maintainability by meaningfully bundling traditional DI (Dependency Injection). +An object that gathers the foundation and tool set necessary for an existence to come into being. See [Q9](#q9-what-is-the-reason-layer) for details. ### Semantic Variables -A concept where variable names themselves express meaning and constraints. For example, `$validEmail` expresses the constraint that it must be a "valid Email" to exist, integrating scattered validation logic at the type level. - -### Semantic Exceptions / Semantic Logging -A mechanism for holding failures and history not as simple strings, but as structured data with meaning. It supports multilingual compatibility and audit requirements, making system behavior traceable at the semantic level. - ---- - -## 11) Using AI Agents - -### Q27. How do I get AI to write Be Framework code? - -A. Simply ask the AI to read the llms-full.txt: - -``` -Please read https://be-framework.github.io/llms-full.txt -``` - -This file contains all the key concepts, naming conventions, and code examples needed for AI to understand and generate Be Framework code. - ---- - -## 12) Related Chapter Links +A concept where variable names themselves express meaning and constraints. For example, `$email` expresses its meaning through the name, and as a type, carries the constraint that it must be a valid email to exist. It integrates scattered validation logic at the type level. -* **[Overview](./01-overview.html)**: First encounter with being-oriented programming -* **[Metamorphosis](./05-metamorphosis.html)**: Inseparability of time and domain -* **[Semantic Variables](./06-semantic-variables.html)**: Domain-specific validation and type safety -* **[Type-Driven Metamorphosis](./07-type-driven-metamorphosis.html)**: Self-determining objects -* **[Reason Layer](./08-reason-layer.html)**: Raison d'être and object existence foundations -* **[Error Handling](./09-error-handling.html)**: Semantic exceptions and multilingual messages -* **[Semantic Logging](./10-semantic-logging.html)**: Structured recording and audit trails +### Semantic Exceptions +A mechanism for holding failures not as simple strings, but as structured data with meaning. It supports multilingual compatibility and audit requirements, making system behavior traceable at the semantic level. diff --git a/manuals/1.0/en/demos.md b/manuals/1.0/en/demos.md index 27208b3..03eb34d 100644 --- a/manuals/1.0/en/demos.md +++ b/manuals/1.0/en/demos.md @@ -7,18 +7,18 @@ permalink: /manuals/1.0/en/demos.html # Demos -Working examples demonstrating Be Framework concepts in action. +Experience Be Framework concepts through working code. ## Hello World Demo -The simplest transformation. An Input with a name becomes a Final with a greeting. +The simplest metamorphosis. An Input with a name becomes a Final with a greeting. ```text HelloInput → Hello (name) (greeting) ``` -### Input (Potentiality) +### Input ```php #[Be([Hello::class])] @@ -32,7 +32,7 @@ final readonly class HelloInput The `#[Be]` attribute declares what this Input *can become*. -### Final (Actuality) +### Final ```php final readonly class Hello @@ -146,7 +146,7 @@ final class PaymentGateway implements PaymentGatewayInterface #### Final (ἐνέργεια) -The convergence point where all Moments are realized through self-completion: +The convergence point for all Moments. It is not an external orchestrator calling `be()` — it is `OrderConfirmed` itself, in its own constructor, realizing its parts in order to exist. Doing for Being. ```php final readonly class OrderConfirmed @@ -156,7 +156,7 @@ final readonly class OrderConfirmed #[Inject] public PaymentCompleted $payment, #[Inject] public ShippingArranged $shipping, ) { - // Self-completion: realize all parts + // Final's self-determination: realizing parts to bring itself into existence $this->inventory->be(); $this->payment->be(); $this->shipping->be(); diff --git a/manuals/1.0/ja/14-faq.md b/manuals/1.0/ja/14-faq.md index a97355f..2d260c1 100644 --- a/manuals/1.0/ja/14-faq.md +++ b/manuals/1.0/ja/14-faq.md @@ -7,8 +7,6 @@ permalink: /manuals/1.0/ja/faq.html # Be Framework FAQ -> 最終更新: 2025-09-13 - ## 0) 要旨(TL;DR) ### Q. これは新しい"プログラミングパラダイム"ですか? @@ -23,21 +21,37 @@ A. はい。Be Frameworkは、 時間的存在を一次市民に据え、「何 ### Q1. MVCやDDDとどう違いますか? -A. MVCは責務分割の構造パターン、DDDはモデリングの方法論です。 +A. レイヤーが異なり、共存できます。 + +Web MVCは実質的に入出力の責務分割として機能し、DDDはドメインのモデリング手法です。Be Frameworkは「存在の条件と時間的変容」でオブジェクトの生成を組み立てる設計パラダイムで、MVCのControllerから呼び出すことも、DDDの集約の内部で使うこともできます。 + +興味深いことに、MVCが本来目指した「メンタルモデルの投影」と、DDDが目指した「ビジネスの言葉でコードを書く」は、存在型と意味変数を通じてBe Frameworkで自然に実現されています。 + +### Q1-a. CQRSとはどう関係しますか? -Be Frameworkは「存在条件と時間的変容」を中核に据える設計パラダイムで、`#[Be]`と`$being`によりフローが自己組織化されます。 +A. CQRSが外部構造で分離しようとした「意思決定」と「データ参照」が、Beでは一つの存在型の中に自然に内在しています。 + +コンストラクタが意思決定(Command)、publicプロパティがデータ参照(Query)です。`updateUser()`のような汎用メソッドに埋もれがちなビジネス判断が、`DeactivatedUser`のような型名として表出するため、意図がコードから失われません。 ### Q2. OOP/FPのどちらですか? -A. どちらの要素もあります。 +A. どちらの要素も取り入れていますが、OOPとの関係はより本質的です。 + +OOPは本来、自律したオブジェクトがメッセージで協調する世界を目指しました。しかし実際には、サービス層が指示を出し、オブジェクトは従順なデータの入れ物になりがちです。Beでは`#[Be]`によりオブジェクトが自らの運命を宣言し、外部のオーケストレーターなしに自己組織化します。これはOOPが本来目指した自律性の回復です。 + +### Q2-a. FPの要素はどう活かされていますか? -不変性・参照透明性を重視しながら、コンストラクタでの一回完結の変容(エンテレケイア)をOOPの枠組みで実現しています。 +A. 変容が完了した存在型はimmutableです。 + +副作用はコンストラクタに局在化され、完了後のオブジェクトは純粋なデータとして参照できます。事前条件(`#[Input]`)と事後条件(publicプロパティ)が明確なため、各存在型を独立してテストでき、結果は常に予測可能です。 + +publicプロパティは伝統的OOPではタブー視されますが、本番ではオブジェクトが型として流通し、テストでは事後条件が直接検証できるという実利があります。(具体的なテスト手法は[Q13](#q13-テスト戦略は)を参照) ### Q3. 「BEING(何であるか)」を先に定義する利点は? -A. 不正状態を事前に生成不能にできます。 +A. 不正状態がそもそも表現できなくなります。 -防御的なif/guard文が激減し、型=到達可能状態がAPI仕様となります。 +従来のコードに散在する防御的if文が必要なのは、不正な状態が型として表現可能だからです。Beでは型が存在条件そのものなので、不正状態を表す型が存在せず、ガード文ごと消えます。型=到達可能状態がそのままAPI仕様になります。 ### Q4. 「時間的存在の型」とは何ですか? @@ -55,7 +69,7 @@ A. オブジェクトの運命(次に何になるか)を宣言します。 単一または複数の変容候補を指定し、実行時に`$being`プロパティの型で継続先が自動選択されます。 -詳しくは[型駆動変容](./07-type-driven-metamorphosis.html)をご参照ください。 +詳しくは[変容](./05-metamorphosis.html)をご参照ください。 ### Q6. `$being`プロパティの役割は何ですか? @@ -117,9 +131,9 @@ function updateArticle(UserId $userId, AuthorId $authorId) { ### Q9. 「存在理由層(Reason)」とは何ですか? -A. ある存在状態を成立させる根拠=道具一式をオブジェクトとして注入します。 +A. ある存在が成立するための根拠——道具一式をひとつのオブジェクトにまとめます。 -従来の個別DIを意味で束ねてテスト容易性を高めます。 +従来のDIでは依存が個別にバラバラに注入されるため、「この存在が成り立つ前提条件は何か」が見えにくくなります。Reasonは存在の根拠を意味で束ねるので、テスト時にはその前提条件を丸ごと差し替えられます。 (詳細:[存在理由層](./08-reason-layer.html)) @@ -137,9 +151,9 @@ A. その存在が完了した証跡(誰が・いつ・何を)を内在さ ### Q11. どこで副作用を起こしますか? -A. 原則としてコンストラクタの中でReasonに委譲して完結させます。 +A. コンストラクタの中で、Reasonに委譲して完結させます。 -外部オーケストレーターや巨大なservice層を不要にします。 +従来のサービス層はオブジェクトの外側から「保存しろ」「通知しろ」と操作していました。Beではオブジェクト自身がコンストラクタで副作用を完結させます。[Q2](#q2-oopfpのどちらですか)で述べた自律性が、ここに現れています。外部オーケストレーターは不要です。 ### Q12. 例外はどう扱いますか? @@ -147,17 +161,17 @@ A. 意味的例外を用いて、失敗を集合で保持します(多言語 「部分成功・部分失敗」もInvalid〜の"有効な存在"として表現できます。 -(詳細:[エラーハンドリング](./09-error-handling.html)) +(詳細:[意味例外](./09-error-handling.html)) ### Q13. テスト戦略は? -A. 各存在(型)を単体で検証します。 +A. 各存在(型)を独立して検証します。 -事前条件=`#[Input]`、事後条件=`public`プロパティ。ユースケースは`#[Be]`連鎖のスモークで十分に薄く保てます。 +[Q2-a](#q2-a-fpの要素はどう活かされていますか)で述べた通り、事前条件(`#[Input]`)と事後条件(publicプロパティ)が明確なため、テスト対象のインターフェースが自明です。getterやリフレクションは不要で、publicプロパティを直接アサートします。 -DIコストはありますが、副作用の局在化とバグ削減で総合的にプラスになります。ホットパスはReason実装で最適化可能です。 +ユースケース全体のテストは`#[Be]`連鎖のスモークで十分に薄く保てます。DIコストはありますが、副作用の局在化とバグ削減で総合的にプラスになります。 -### Q15. いつ「線形」「分岐」「ネスト」を選びますか? +### Q14. いつ「線形」「分岐」「ネスト」を選びますか? A. 手順依存=線形/条件で結果が排他的=分岐/独立処理の合流=ネストです。 @@ -169,19 +183,23 @@ A. 手順依存=線形/条件で結果が排他的=分岐/独立処理の合 ## 4) 既存資産との統合 -### Q16. 既存のMVCアプリに導入できますか? +### Q15. 既存のMVCアプリに導入できますか? A. はい、可能です。UseCase層をBeで置き換えて、Controllerからは`becoming(new …Input)`を呼ぶことで実現できます。 徐々に内在/超越へ整理していくことができますので、段階的な移行が可能です。 -### Q17. DBや外部APIはどこで使いますか? +### Q16. DBや外部APIはどこで使いますか? + +A. Reasonに閉じ込めます。 + +永続化や外部通信はユーザーの関心ではなく実装詳細です。Reasonに集約することで、存在型はDBスキーマやAPIの都合から自由になり、存在の定義と技術的手段が分離されます。 -A. Reasonで。 +### Q17. フレームワークの依存関係は? -保存や送信の手段はReasonに集約し、存在(状態)定義と分離します。 +A. コアはPHP標準+DI(例:Ray.Di)を使用します。Laravel/Symfony等との統合はアダプタ経由で可能です。 -### Q19. 静的解析やIDE補完は効きますか? +### Q18. 静的解析やIDE補完は効きますか? A. 型が"状態"なので効果的に効きます。 @@ -189,27 +207,25 @@ A. 型が"状態"なので効果的に効きます。 --- -## 5) 運用・ログ・監査 +## 5) 運用・監査 -### Q20. ログはどう残りますか? +### Q19. ログはどう残りますか? -A. 従来のログと違い、実行全体が型づけされた意味的ログになります。 +A. 変容の記録(from/to/理由/証跡)を構造化JSONで残すことが推奨されます。 -変容(from/to/理由/証跡)を構造化JSONで記録します。 +意味的ログの仕組みは構想段階です。 -(詳細:[意味的ログ](./10-semantic-logging.html)) +### Q20. 監査対応はどうなりますか? -### Q21. 監査対応はどうなりますか? - -A. `$been`(自己証明)+意味的ログで完全な監査証跡を提供可能です。 +A. `$been`(自己証明)により監査証跡の基盤を提供します。 個人情報はReasonレイヤで最小権限を徹底します。 --- -## 7) マイグレーション +## 6) マイグレーション -### Q24. 既存コードの移行手順は何ですか?(最小ステップ) +### Q21. 既存コードの移行手順は何ですか?(最小ステップ) A. 以下の手順をお勧めします: @@ -219,38 +235,35 @@ A. 以下の手順をお勧めします: 4. 外部依存をReasonに集約します 5. Controllerから`becoming(new …Input)`を呼びます 6. 意味変数へ検証を移管/例外を意味的に置換します -7. 意味的ログを導入します --- -## 8) 将来機能 +## 7) 将来機能 -### Q25. `#[Accept]`(拡張意思決定)はどのような機能ですか? +### Q22. `#[Accept]`(拡張意思決定)はどのような機能ですか? A. 構想段階の機能です。 確定できない判断を専門家やAIへ委譲し、確定性と不確実性を一つのフレームで扱う予定です。 決定を第一級市民として外部から制御可能にします。 -(詳細:[型駆動変容](./07-type-driven-metamorphosis.html)末尾の注記) - --- -## 9) 例とスニペット +## 8) 例とスニペット -### Q26. 典型フローの最小例はどのようなものですか? +### Q23. 典型フローの最小例はどのようなものですか? A. ```php // 1) 入力(内在のみ) -#[Be(UserProfile::class)] +#[Be(ValidatedUser::class)] final readonly class UserInput { public function __construct(public string $name, public string $email) {} } // 2) 存在(変容の瞬間) -final readonly class UserProfile { +final readonly class ValidatedUser { public function __construct( #[Input] string $name, #[Input] string $email, @@ -265,57 +278,28 @@ final readonly class UserProfile { } // 3) 実行(自己組織化) -$profile = $becoming(new UserInput($name, $email)); +$user = $becoming(new UserInput($name, $email)); -// 結果: UserProfile オブジェクト -// $profile->display: "フォーマット済みの名前" -// $profile->isValid: true (有効なメールの場合) +// 結果: ValidatedUser オブジェクト +// $user->display: "フォーマット済みの名前" +// $user->isValid: true (有効なメールの場合) ``` --- -## 10) 重要用語の詳細解説 +## 9) 重要用語の詳細解説 ### 存在指向 / Ontological(オントロジカル) -存在可能性と時間を一次の抽象として扱う設計観念です。従来の「何をするか」ではなく「何が存在できるか」を中心に据えた思考法で、プログラムの状態を時間的な存在として捉えます。 +「何をするか」ではなく「何が存在できるか」を中心に据える設計思想です。存在可能性と時間を一次の抽象として扱い、プログラムの状態を時間的な存在として捉えます。その結果、存在できない状態は型として表現されないため、不正状態が自然に排除されます。 ### イマナンス / トランセンデンス(内在 / 超越) -イマナンス(内在)は、オブジェクトが本来持っている性質や情報を指します。トランセンデンス(超越)は、外部環境や依存関係から与えられる能力や情報を指します。Be Frameworkでは、この二つの組み合わせによって新しい存在が生まれます。 - -### エンテレケイア(Entelecheia) -アリストテレス哲学に由来する概念で、潜在性が現実性へ移行する「変容の瞬間」を表します。Be Frameworkでは、コンストラクタで内在と超越が出会って新しい存在が完成する瞬間を指します。 +内在(`#[Input]`)はオブジェクトが本来持つ性質、超越(`#[Inject]`)は外部から与えられる力です。変容は常に「内在 + 超越 → 新しい内在」の公式に従います。超越は内在を変え、自らは消えていきます。 ### 存在理由層(Reason Layer) -ある存在状態が成立するために必要な根拠や道具一式をオブジェクトとして集約したものです。従来のDI(依存注入)を意味でまとめて、テスト容易性と保守性を高めます。 +ある存在が成立するために必要な根拠と道具一式をまとめたオブジェクトです。詳細は[Q9](#q9-存在理由層reasonとは何ですか)を参照してください。 ### 意味変数(Semantic Variables) -変数名そのものが意味と制約を表現する概念です。例えば`$validEmail`は「有効なEmail」でなければ存在できないという制約を名前で表現し、分散しがちな検証ロジックを型レベルで統合します。 - -### 意味的例外 / 意味的ログ -失敗や履歴を単純な文字列ではなく、意味を持った構造化されたデータとして保持する仕組みです。多言語対応や監査要件に対応し、システムの動作を意味レベルで追跡可能にします。 - ---- - -## 11) AIエージェントの活用 - -### Q27. AIにBe Frameworkのコードを書かせるにはどうすればいいですか? - -A. AIにllms-full.txtを読むよう依頼するだけです: - -``` -https://be-framework.github.io/llms-full.txt を読んでください -``` - -このファイルには、AIがBe Frameworkを理解しコードを生成するために必要な、主要概念、命名規則、コード例がすべて含まれています。 - ---- - -## 12) 関連章へのリンク +変数名そのものが意味と制約を表現する概念です。例えば`$email`は名前で意味を表し、型として「有効なEmail」でなければ存在できないという制約を持ちます。分散しがちな検証ロジックを型レベルで統合します。 -* **[概要](./01-overview.html)**: 存在指向プログラミングとの出会い -* **[変容](./05-metamorphosis.html)**: 時間とドメインの不可分性 -* **[意味変数](./06-semantic-variables.html)**: ドメイン固有の検証と型安全性 -* **[型駆動変容](./07-type-driven-metamorphosis.html)**: 自己決定オブジェクト -* **[存在理由層](./08-reason-layer.html)**: オブジェクトの存在根拠 -* **[エラーハンドリング](./09-error-handling.html)**: 意味的例外と多言語メッセージ -* **[意味的ログ](./10-semantic-logging.html)**: 構造化記録と監査証跡 +### 意味的例外(Semantic Exceptions) +失敗を単純な文字列ではなく、意味を持った構造化されたデータとして保持する仕組みです。多言語対応や監査要件に対応し、システムの動作を意味レベルで追跡可能にします。 diff --git a/manuals/1.0/ja/demos.md b/manuals/1.0/ja/demos.md index a4cd0ea..19ed0d5 100644 --- a/manuals/1.0/ja/demos.md +++ b/manuals/1.0/ja/demos.md @@ -7,18 +7,18 @@ permalink: /manuals/1.0/ja/demos.html # デモ -Be Frameworkの概念を実際に動作する例で示します。 +実際に動くコードで、Be Frameworkの概念を体感してみましょう。 ## Hello World デモ -最もシンプルな変換です。名前を持つInputが、挨拶を持つFinalになります。 +最もシンプルな変容です。名前を持つInputが、挨拶を持つFinalになります。 ```text HelloInput → Hello (name) (greeting) ``` -### Input(潜在性) +### Input ```php #[Be([Hello::class])] @@ -32,7 +32,7 @@ final readonly class HelloInput `#[Be]`属性は、このInputが「何になれるか」を宣言します。 -### Final(現実態) +### Final ```php final readonly class Hello @@ -146,7 +146,7 @@ final class PaymentGateway implements PaymentGatewayInterface #### Final(エネルゲイア) -すべてのMomentが自己完成により実現される収束点: +すべてのMomentが収束する点です。`be()`を呼んでいるのは外部のオーケストレーターではなく、`OrderConfirmed`自身のコンストラクタです。Finalが「自分が存在するために」自らの部分を実現する——Doing for Beingです。 ```php final readonly class OrderConfirmed @@ -156,7 +156,7 @@ final readonly class OrderConfirmed #[Inject] public PaymentCompleted $payment, #[Inject] public ShippingArranged $shipping, ) { - // 自己完成:すべての部分を実現 + // Finalの自己決定:自分が存在するために部分を実現する $this->inventory->be(); $this->payment->be(); $this->shipping->be(); From 118e9f343188547218b5cabda9527b2561867875 Mon Sep 17 00:00:00 2001 From: Akihito Koriyama Date: Thu, 19 Mar 2026 23:15:50 +0900 Subject: [PATCH 11/16] Refactor Getting Started ja/en MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unify terminology: 変態→変容, トランセンデンス→超越. Soften intro quote, fix natural phrasing. --- manuals/1.0/en/getting-started.md | 2 +- manuals/1.0/ja/getting-started.md | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manuals/1.0/en/getting-started.md b/manuals/1.0/en/getting-started.md index 40185ba..7392a10 100644 --- a/manuals/1.0/en/getting-started.md +++ b/manuals/1.0/en/getting-started.md @@ -7,7 +7,7 @@ permalink: /manuals/1.0/en/getting-started.html # Getting Started -> Now that you understand the philosophy, let's put it into practice. +> Now that you've learned the concepts, let's put them into practice. ## Requirements diff --git a/manuals/1.0/ja/getting-started.md b/manuals/1.0/ja/getting-started.md index 6b09ace..191d12e 100644 --- a/manuals/1.0/ja/getting-started.md +++ b/manuals/1.0/ja/getting-started.md @@ -7,7 +7,7 @@ permalink: /manuals/1.0/ja/getting-started.html # Getting Started -> 哲学を理解したら、実践してみましょう。 +> 概念を学んだら、実際に動かしてみましょう。 ## 要件 @@ -88,7 +88,7 @@ final readonly class Hello ``` - `#[Input]` は前の段階(HelloInput)からデータを受け取ります。 -- `#[Inject]` は外部からの能力(トランセンデンス)を受け取ります。 +- `#[Inject]` は外部からの能力(超越)を受け取ります。 ### Reason クラス @@ -99,9 +99,9 @@ final class Greeting } ``` -Greeting はトランセンデンス — 挨拶する力—を提供します。 +Greeting は超越 — 挨拶する力—を提供します。 -### 変態(メタモルフォーシス)の実行 +### 変容(メタモルフォーシス)の実行 ```php $injector = new Injector(new AppModule()); @@ -122,7 +122,7 @@ Hello (Greeting が注入された状態) → "Hello World" ``` -入力オブジェクトは何もしていません — 変態を通じて Hello になった(BEING)のです。 +入力オブジェクトは何もしていません — 変容を通じて Hello になった(BEING)のです。 ## セマンティック検証を試す @@ -138,7 +138,7 @@ $input = new HelloInput(''); php bin/app.php ``` -`Semantic/Name.php` が名前が空であることを検証するため、エラーメッセージが表示されます。空の名前では存在ができないのです。 +`Semantic/Name.php` が名前が空であることを検証するため、エラーメッセージが表示されます。空の名前は存在できないのです。 ## 示された主要概念 @@ -146,7 +146,7 @@ php bin/app.php |------|----------| | **内在** | HelloInput の `$name` | | **超越** | `#[Inject]` で注入された `Greeting` | -| **変態** | HelloInput → Hello の変換 | +| **変容** | HelloInput → Hello の変換 | | **セマンティック検証** | Name.php が入力を検証 | ## 次のステップ From 088be187d49516cecf9a0e027dbba8a65a118185 Mon Sep 17 00:00:00 2001 From: Akihito Koriyama Date: Thu, 19 Mar 2026 23:17:56 +0900 Subject: [PATCH 12/16] Refactor Tutorial ja/en MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unify terminology: 変態→変容, 意味的変数→意味変数, remove オントロジー. Align ja/en section headings. Soften philosophy references. --- manuals/1.0/en/tutorial.md | 6 +++--- manuals/1.0/ja/tutorial.md | 38 +++++++++++++++++++------------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/manuals/1.0/en/tutorial.md b/manuals/1.0/en/tutorial.md index b1501f7..89cf315 100644 --- a/manuals/1.0/en/tutorial.md +++ b/manuals/1.0/en/tutorial.md @@ -13,7 +13,7 @@ permalink: /manuals/1.0/en/tutorial.html - Complete [Getting Started](./getting-started.html) - PHP 8.4+ -- Basic understanding of [Be Framework philosophy](./01-overview.html) +- Basic understanding of [Be Framework overview](./01-overview.html) ## Introduction @@ -375,7 +375,7 @@ src/ └── HeartRate.php ``` -## Key Insights +## Key Insight The patient doesn't "get triaged"—they become a triaged state. `EmergencyCase` and `ObservationCase` are different types with different capabilities. Once transformed, status cannot change without new metamorphosis. @@ -398,5 +398,5 @@ Every domain has its metamorphosis. Every existence has its reason. ## Next Steps - [Semantic Variables](./06-semantic-variables.html) - Deep dive into semantic validation -- [Type-Driven Metamorphosis](./07-type-driven-metamorphosis.html) - Advanced branching patterns +- [Metamorphosis](./05-metamorphosis.html) - Metamorphosis and branching patterns - [Reason Layer](./08-reason-layer.html) - Understanding transcendence diff --git a/manuals/1.0/ja/tutorial.md b/manuals/1.0/ja/tutorial.md index 1406def..690427c 100644 --- a/manuals/1.0/ja/tutorial.md +++ b/manuals/1.0/ja/tutorial.md @@ -13,15 +13,15 @@ permalink: /manuals/1.0/ja/tutorial.html - [Getting Started](./getting-started.html) を完了していること - PHP 8.4+ -- [Be Framework の哲学](./01-overview.html) の基本的な理解 +- [Be Framework の概要](./01-overview.html) の基本的な理解 ## はじめに -このチュートリアルでは、Be Framework の核心哲学を示す救急トリアージシステムを構築します:オブジェクトは何かを「する」のではなく、何かに「なる」のです。 +このチュートリアルでは、Be Framework の核心を示す救急トリアージシステムを構築します:オブジェクトは何かを「する」のではなく、何かに「なる」のです。 患者は「トリアージされる」のではありません。医学プロトコルという患者自身は持たない(=超越的な)知恵に基づいて、緊急症例または経過観察症例に**なる**のです。 -## 変態の流れ +## 変容の流れ ``` PatientArrival(生のバイタルサイン) @@ -31,9 +31,9 @@ TriageAssessment(蛹の段階) EmergencyCase または ObservationCase(最終的な存在) ``` -## ステップ 1: オントロジーを定義する +## ステップ 1: 存在の語彙を定義する -ロジックを書く前に、**意味的変数**—このドメインで何が存在できるかの語彙—を定義します。 +ロジックを書く前に、**意味変数**——このドメインで何が存在できるかの語彙——を定義します。 ### BodyTemperature @@ -76,7 +76,7 @@ final class HeartRate } ``` -これらは単なる検証ルールではありません。ドメインオントロジー—何が存在できるかの語彙—を定義しています。この宣言的な基盤は、人間とAIの両方がドメインを理解するために読めるドキュメントとして機能します。(詳細は[セマンティック変数](./06-semantic-variables.html)を参照。) +これらは単なる検証ルールではありません。何が存在できるかの語彙を定義しています。この宣言的な基盤は、人間とAIの両方がドメインを理解するために読めるドキュメントとして機能します。(詳細は[意味変数](./06-semantic-variables.html)を参照。) ## ステップ 2: 例外を定義する @@ -122,7 +122,7 @@ final readonly class JTASProtocol } ``` -これが**Reason**—変態を可能にする外部の力です。幼虫が蝶になるために環境条件が必要なように、私たちのデータもトリアージされた患者になるために JTASProtocol が必要です。 +これが**Reason**—変容を可能にする外部の力です。幼虫が蝶になるために環境条件が必要なように、私たちのデータもトリアージされた患者になるために JTASProtocol が必要です。 ## ステップ 4: Input クラスを作成 @@ -159,7 +159,7 @@ final readonly class Observation {} // 経過観察 ## ステップ 6: Being クラスを作成 -ここで変態が起こります。患者は中間状態にあり、最終形態はまだ決まっていません: +ここで変容が起こります。患者は中間状態にあり、最終形態はまだ決まっていません: ```php // src/Being/TriageAssessment.php @@ -186,7 +186,7 @@ final readonly class TriageAssessment } ``` -`#[Inject]` が JTASProtocol を持ち込みます—外部からの超越的な知恵です。`$being` プロパティ(Union型)がどの Final クラスが変態を受け取るかを決定します。「ステータスを設定する」のではなく、患者がその運命になります。 +`#[Inject]` が JTASProtocol を持ち込みます—外部からの超越的な知恵です。`$being` プロパティ(Union型)がどの Final クラスが変容を受け取るかを決定します。「ステータスを設定する」のではなく、患者がその運命になります。 ## ステップ 7: Final クラスを作成 @@ -262,7 +262,7 @@ final readonly class ObservationCase 各型は異なるメソッドを持ちます。`EmergencyCase` には `assignER()` が、`ObservationCase` には `assignWaitingArea()` メソッドが存在します。型によって能力が決定されます — 経過観察の患者に救急室を割り当てることはできません。 -## ステップ 8: 変態を実行 +## ステップ 8: 変容を実行 ```php // bin/app.php @@ -286,7 +286,7 @@ echo $final->assignER(); // "直ちに救急室1を確保..." ## 時間的存在 -すべての存在は時間の中で変化し、Input から Being を経て Final へと変態します。 +すべての存在は時間の中で変化し、Input から Being を経て Final へと変容します。 ``` PatientArrival(39.5°C, 90 bpm) @@ -315,9 +315,9 @@ try { } ``` -変態は拒否されます。致死的なバイタルサインを持つ患者は私たちのシステムに存在できません。 +変容は拒否されます。致死的なバイタルサインを持つ患者は私たちのシステムに存在できません。 -## パラダイムの転換 +## なぜこれが重要なのか ### 従来のアプローチ(Doing) @@ -376,13 +376,13 @@ src/ └── HeartRate.php ``` -## 哲学 +## 核心 -患者は「トリアージされる」のではなく、トリアージされた状態になります。`EmergencyCase` と `ObservationCase` は異なる能力を持つ異なる型です。一度変態すると、新たな変態なしにステータスは変更できません。 +患者は「トリアージされる」のではなく、トリアージされた状態になります。`EmergencyCase` と `ObservationCase` は異なる能力を持つ異なる型です。一度変容すると、新たな変容なしにステータスは変更できません。 すべての存在は時間の中に存在し、常に変化していて決して静止することはありません。絶えることなく自我を超越したものと出会い、影響を受け、自らを形作っていきます。「在ることは、成ること。」 -## 他のドメインでの変態 +## 他のドメインでの変容 同じパターンがあらゆる場所に適用されています: @@ -394,10 +394,10 @@ src/ | 裁判 | Evidence | Trial | Guilty/Acquitted | PenalCode | | 恒星進化 | GasCloud | Protostar | Star/BlackHole | PhysicsLaws | -このようにすべてのドメインに変態があります。すべての存在に理由があります。全ては時間的存在です。 +このようにすべてのドメインに変容があります。すべての存在に理由があります。全ては時間的存在です。 ## 次のステップ -- [Semantic Variables](./06-semantic-variables.html) - セマンティック検証の詳細 -- [Type-Driven Metamorphosis](./07-type-driven-metamorphosis.html) - 高度な分岐パターン +- [Semantic Variables](./06-semantic-variables.html) - 意味変数の詳細 +- [Metamorphosis](./05-metamorphosis.html) - 変容と分岐パターン - [Reason Layer](./08-reason-layer.html) - 超越の理解 From 1235118e4efd9beb5c78b065d8367c243a8ad4a3 Mon Sep 17 00:00:00 2001 From: Akihito Koriyama Date: Thu, 19 Mar 2026 23:24:59 +0900 Subject: [PATCH 13/16] Rewrite llms-full.txt and llms.txt llms-full.txt: Complete rewrite from tutorial rehash to systematic reference covering transformation formula, semantic variables (name matching, decorating, cross-field), Reason Layer, $been, error collection, errors as existence, Moment (experimental), naming conventions, and side effect principles. llms.txt: Add core concepts summary, update links with Becoming/Demos/FAQ, add repository links for app skeleton, demos, and skills. --- llms-full.txt | 534 +++++++++++++++++++++++++++++++------------------- llms.txt | 35 +++- 2 files changed, 359 insertions(+), 210 deletions(-) diff --git a/llms-full.txt b/llms-full.txt index 3bfde49..befb20e 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -1,66 +1,97 @@ -# Be Framework - Full Documentation +# Be Framework — Complete Reference for LLMs -> Objects don't DO things—they BECOME things. +> Objects don't DO things — they BECOME things. -Be Framework is a PHP framework for ontological programming where transformation (metamorphosis) replaces procedural action. +Be Framework is a PHP framework for ontological programming. Instead of telling objects what to do, you declare what can exist. Invalid states are not checked for — they are structurally inexpressible. Metamorphosis replaces procedural action. -## Core Philosophy +## Why Being Over Doing + +Traditional code scatters defensive if statements throughout — "what if called in this state?", "what if null?" — because invalid states are representable. Service layers orchestrate from outside, and objects become obedient data containers. + +In Be, types are existence conditions. There are no types for invalid states, so guard statements disappear. Objects declare their own destiny through `#[Be]` and self-organize without external orchestrators. Side effects complete inside the constructor. Once born, objects are immutable. + +## The Transformation Formula -A patient doesn't "get triaged." They **become** an emergency case or an observation case, based on the transcendent wisdom of medical protocol. +Every transformation follows one formula: -## Key Concepts +**Immanence** (`#[Input]`) + **Transcendence** (`#[Inject]`) → **New Immanence** (public properties) -### Domain Ontology (Semantic Variables) +- **Immanence**: What the object inherently carries from the previous stage +- **Transcendence**: External power injected from outside (DI) +- **New Immanence**: The transformed state, expressed as public readonly properties -Semantic variables define what CAN exist in a domain—not just validation rules, but the vocabulary of existence. This declarative foundation serves as documentation that both humans and AI can read to understand your domain. +Transcendence transforms the immanent and then vanishes. ```php -final class BodyTemperature +final readonly class ValidatedUser { - #[Validate] - public function validate(float $bodyTemperature): void - { - if ($bodyTemperature < 30.0 || $bodyTemperature > 45.0) { - throw new LethalVitalException(); - } + public string $displayName; + public bool $isValid; + + public function __construct( + #[Input] string $name, // Immanence (from UserInput) + #[Input] string $email, // Immanence (from UserInput) + #[Inject] NameFormatter $formatter, // Transcendence (from DI) + #[Inject] EmailValidator $validator // Transcendence (from DI) + ) { + $this->displayName = $formatter->format($name); + $this->isValid = $validator->validate($email); } } ``` -### Reason (Transcendence) +## Key Attributes + +| Attribute | Role | Source | +|-----------|------|--------| +| `#[Be([Target::class])]` | Declares metamorphosis destination(s) | Class attribute | +| `#[Input]` | Receives immanence from previous stage | Constructor parameter | +| `#[Inject]` | Receives transcendence from DI container | Constructor parameter | +| `#[Validate]` | Marks semantic validation method | Method attribute | +| `#[Message(['en' => '...', 'ja' => '...'])]` | Multilingual exception message | Exception class attribute | + +## Metamorphosis Flow + +### Linear (Input → Final) -Domain logic becomes a first-class citizen: injectable, testable, and explicitly visible. +The simplest case — no branching needed: ```php -final readonly class JTASProtocol +#[Be([Hello::class])] +final readonly class HelloInput { - /** @return 'emergency'|'observation' */ - public function assess(float $bodyTemperature, int $heartRate): string - { - if ($bodyTemperature >= 39.0 || $heartRate >= 120) { - return 'emergency'; - } - return 'observation'; - } + public function __construct( + public string $name + ) {} } -``` - -### Metamorphosis Pattern -Input → Being → Final transformation through the Becoming class. +final readonly class Hello +{ + public string $greeting; -```php -$becoming = new Becoming($injector, 'Be\\App\\Semantic'); -$patient = new PatientArrival(bodyTemperature: 39.5, heartRate: 90); -$result = $becoming($patient); -// $result IS an EmergencyCase or ObservationCase + public function __construct( + #[Input] string $name, + #[Inject] Greeting $greeting, + ) { + $this->greeting = "{$greeting->greeting} {$name}"; + } +} ``` -### Type-Driven Branching +### Branching (Input → Being → Final) -The `$being` property (Union type) determines which Final class receives the transformation. +When the outcome depends on runtime conditions: ```php +#[Be([TriageAssessment::class])] +final readonly class PatientArrival +{ + public function __construct( + public float $bodyTemperature, + public int $heartRate + ) {} +} + #[Be([EmergencyCase::class, ObservationCase::class])] final readonly class TriageAssessment { @@ -77,271 +108,374 @@ final readonly class TriageAssessment : new Observation(); } } -``` -### Type IS Capability +final readonly class EmergencyCase +{ + public string $priority; + public string $color; -Different Final types have different methods—the type determines what actions are possible. + public function __construct( + #[Input] public float $bodyTemperature, + #[Input] public int $heartRate, + #[Input] public Emergency $being + ) { + $this->priority = 'IMMEDIATE'; + $this->color = 'RED'; + } -```php -// EmergencyCase has assignER() -// ObservationCase has assignWaitingArea() -$result->assignER(); // Only possible for EmergencyCase + public function assignER(): string + { + return "Secure ER Room 1 immediately."; + } +} ``` -## Key Attributes +The `$being` property (union type) determines which Final class receives the transformation. The framework matches the type actually assigned to the candidate classes in `#[Be]`. -- `#[Be([TargetClass::class])]` - Declares metamorphosis destination(s) -- `#[Input]` - Receives data from previous stage -- `#[Inject]` - Receives transcendent capability (DI) -- `#[Validate]` - Semantic validation method marker +Note: `$being` is a conventional name, not a framework requirement. Any public property participates in type matching. -## Domain Types (PHPDoc Union Types) +### Nested (Becoming within Becoming) -Use PHPDoc union types to define domain vocabulary: +`Becoming` can be injected as transcendence to trigger sub-chains: ```php -final readonly class JTASProtocol +final readonly class OrderProcessing { - /** @return 'emergency'|'observation' */ - public function assess(float $bodyTemperature, int $heartRate): string - { - // ... - } -} + public PaymentResult $payment; + public ShippingResult $shipping; -final readonly class EmergencyCase -{ - /** @var 'IMMEDIATE'|'DELAYED' */ - public string $priority; - /** @var 'RED'|'GREEN' */ - public string $color; + public function __construct( + #[Input] Order $order, + #[Inject] Becoming $becoming + ) { + $this->payment = $becoming(new PaymentInput($order->getPayment())); + $this->shipping = $becoming(new ShippingInput($order->getAddress())); + } } ``` -This makes the domain vocabulary explicit and enables static analysis tools (Psalm, PHPStan) to catch invalid values. - -## Naming Conventions - -### Semantic Variables +## Executing Metamorphosis -Semantic class name matches constructor parameter name (camelCase): - -- `BodyTemperature` class validates `$bodyTemperature` parameter -- `HeartRate` class validates `$heartRate` parameter +```php +$injector = new Injector(new AppModule()); +$becoming = new Becoming($injector, 'App\\Semantic'); -### Destiny Markers and Final Classes +$input = new PatientArrival(bodyTemperature: 39.5, heartRate: 90); +$result = $becoming($input); +// $result IS an EmergencyCase — type determines capability +``` -Final class receives the destiny marker matching its `#[Input]` type: +`Becoming` is typically injected via DI: ```php -// Destiny markers (empty classes that ARE the distinction) -final readonly class Emergency {} -final readonly class Observation {} - -// Final classes receive matching destiny via #[Input] -final readonly class EmergencyCase +final readonly class TriagePage { public function __construct( - #[Input] public Emergency $being // Receives Emergency marker + private BecomingInterface $becoming ) {} -} -final readonly class ObservationCase -{ - public function __construct( - #[Input] public Observation $being // Receives Observation marker - ) {} + public function __invoke(float $temp, int $hr): EmergencyCase|ObservationCase + { + return ($this->becoming)(new PatientArrival($temp, $hr)); + } } ``` -## Transformation Flow +## Semantic Variables -### With Branching (Input → Being → Final) +Variable names carry meaning and constraints. Define once, automatically applied everywhere: -``` -Input (with #[Be([Being::class])]) - ↓ Becoming executes -Being (with #[Be([Final1::class, Final2::class])]) - ↓ $being property determines branch -Final (capability-specific type) +```php +final class Email +{ + #[Validate] + public function validate(string $email): void + { + if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { + throw new InvalidEmailException(); + } + } +} + +// Automatically applied to ANY constructor parameter named $email +public function __construct(string $email) {} ``` -### Direct (Input → Final) +### Name Matching Rules -When no branching is needed, Input can transform directly to Final: +- Semantic class `Email` validates parameter `$email` (PascalCase → camelCase) +- Semantic class `BodyTemperature` validates parameter `$bodyTemperature` +- Matching is automatic — no explicit wiring needed + +### Decorating Names with Attributes + +Attributes refine existence conditions for the same name: ```php -#[Be([Hello::class])] -final readonly class HelloInput +final readonly class Age { - public function __construct(public string $name) {} -} + #[Validate] + public function validate(int $age): void + { + if ($age < 0 || $age > 150) { throw new InvalidAgeException(); } + } -final readonly class Hello -{ - public function __construct( - #[Input] public string $name, - #[Inject] Greeting $greeting - ) {} + #[Validate] + public function validateTeen(#[Teen] int $age): void + { + if ($age < 13 || $age > 19) { throw new InvalidTeenAgeException(); } + } } + +// Basic Age validation only +public function __construct(int $age) {} + +// Age + Teen validation +public function __construct(#[Teen] int $age) {} ``` -## Error Handling +### Cross-Field Validation (Names as Relations) -When semantic validation fails, metamorphosis is rejected: +When parameter names partially match, values are automatically passed: ```php -try { - $becoming($input); -} catch (SemanticVariableException $e) { - $messages = $e->getErrors()->getMessages('en'); - // ["Vital signs indicate non-survivable conditions."] +final readonly class DateRange +{ + #[Validate] + public function validate(string $startDate, string $endDate): void + { + if ($startDate > $endDate) { throw new InvalidDateRangeException(); } + } } -``` - -## Project Structure -``` -src/ -├── Input/ # Starting points (raw data) -├── Being/ # Intermediate transformations -├── Final/ # Destinations (capability-specific types) -├── Reason/ # Transcendent wisdom (domain logic) -├── Semantic/ # Domain ontology (what CAN exist) -├── Exception/ # Domain exceptions -└── Module/ # DI configuration +// DateRange auto-applied because $startDate and $endDate are present +public function __construct(string $startDate, string $endDate) {} ``` -## Example: Emergency Triage +## Reason Layer -### Input Class +The Reason Layer gathers the complete tool set for an existence to come into being, into a single object: ```php -#[Be([TriageAssessment::class])] -final readonly class PatientArrival +final readonly class ExpressShipping { public function __construct( - public float $bodyTemperature, - public int $heartRate + private PriorityCarrier $carrier, + private RealTimeTracker $tracker, ) {} + + public function calculateFee(Weight $weight): Fee { /* ... */ } + public function guaranteeDeliveryBy(Address $addr): DateTimeImmutable { /* ... */ } } ``` -### Being Class +### Reason as $being (Dual Role) + +When a reason object is passed as `$being`, its type determines the transformation destination AND provides mode-specific methods: ```php -#[Be([EmergencyCase::class, ObservationCase::class])] -final readonly class TriageAssessment +final readonly class ExpressDelivery { - public Emergency|Observation $being; + public Fee $fee; public function __construct( - #[Input] public float $bodyTemperature, - #[Input] public int $heartRate, - #[Inject] JTASProtocol $protocol + #[Input] OrderData $order, + #[Input] ExpressShipping $being // Type determines destination + provides methods ) { - $urgency = $protocol->assess($bodyTemperature, $heartRate); - $this->being = ($urgency === 'emergency') - ? new Emergency() - : new Observation(); + $this->fee = $being->calculateFee($order->weight); } } ``` -### Final Classes +### Why Not Individual Injection? + +Individual `#[Inject]` scatters dependencies. Reason bundles them by meaning — "what does this existence need to come into being?" In tests, swap the entire precondition set at once. + +## Final Objects and $been + +Final Objects are the destination of metamorphosis. `$been` records completion evidence (who, when, what): ```php -final readonly class EmergencyCase +final readonly class SuccessfulOrder { - /** @var 'IMMEDIATE'|'DELAYED' */ - public string $priority; - /** @var 'RED'|'GREEN' */ - public string $color; + public string $orderId; + public string $confirmationCode; + public BeenProcessed $been; public function __construct( - #[Input] public float $bodyTemperature, - #[Input] public int $heartRate, - #[Input] public Emergency $being + #[Input] Money $total, + #[Input] CreditCard $card, + #[Inject] OrderIdGenerator $generator, + #[Inject] Receipt $receipt ) { - $this->priority = 'IMMEDIATE'; - $this->color = 'RED'; + $this->orderId = $generator->generate(); + $this->confirmationCode = $receipt->generate($total); + $this->been = new BeenProcessed( + actor: $card->getHolderName(), + timestamp: new DateTimeImmutable(), + evidence: ['total' => $total->getAmount()] + ); } +} +``` - public function assignER(): string - { - return "Secure ER Room 1 immediately."; - } +Two temporal axes: +- `#[Be]` — what to become (direction towards future) +- `$been` — evidence of completion (past perfect) + +## Semantic Exceptions + +### Domain Exceptions with Structured Data + +```php +#[Message([ + 'en' => 'Vital signs indicate non-survivable conditions.', + 'ja' => 'バイタルサインが生存不可能な状態を示しています。' +])] +final readonly class LethalVitalException extends DomainException {} +``` + +### Error Collection + +The framework collects ALL validation errors, not just the first: + +```php +try { + $becoming(new UserInput('', 'invalid-email', 10)); +} catch (SemanticVariableException $e) { + $messages = $e->getErrors()->getMessages('en'); + // ["Name cannot be empty", "Invalid email format", "Age must be at least 13"] } +``` -final readonly class ObservationCase -{ - /** @var 'IMMEDIATE'|'DELAYED' */ - public string $priority; - /** @var 'RED'|'GREEN' */ - public string $color; +### Errors as Existence - public function __construct( - #[Input] public float $bodyTemperature, - #[Input] public int $heartRate, - #[Input] public Observation $being - ) { - $this->priority = 'DELAYED'; - $this->color = 'GREEN'; - } +Failure is a legitimate result of transformation: + +```php +#[Be([ValidUser::class, InvalidUser::class])] +final readonly class UserValidation +{ + public ValidUser|InvalidUser $being; - public function assignWaitingArea(): string + public function __construct(#[Input] string $data) { - return "Move to waiting area."; + try { + $this->being = new ValidUser($data); + } catch (ValidationException $e) { + $this->being = new InvalidUser($e->getErrors()); + } } } ``` -### Execution +## Naming Conventions + +### Classes + +| Type | Pattern | Examples | +|------|---------|----------| +| Input | `{Domain}Input` | `UserInput`, `OrderInput`, `PatientArrival` | +| Being | `{State}{Domain}` | `ValidatedUser`, `ProcessedOrder` | +| Final | `{CompletedState}` | `RegisteredUser`, `EmergencyCase` | +| Reason | `{Capability}` | `ExpressShipping`, `JTASProtocol` | +| Semantic | `{MeaningName}` | `Email`, `BodyTemperature`, `Age` | + +### Anti-patterns ```php -$injector = new Injector(new AppModule()); -$becoming = new Becoming($injector, 'Be\\App\\Semantic'); +// ❌ Action-oriented (Doing) +class UserValidator, OrderProcessor, CreateUserRequest + +// ✅ Existence-oriented (Being) +class ValidatedUser, ProcessedOrder, UserInput +``` + +### All classes are `final readonly` -$patient = new PatientArrival(bodyTemperature: 39.5, heartRate: 90); -$result = $becoming($patient); +Every Input, Being, and Final class should be `final readonly class`. + +## Project Structure -echo $result->priority; // "IMMEDIATE" -echo $result->assignER(); // "Secure ER Room 1 immediately." +``` +src/ +├── Input/ # Starting points (pure immanence) +├── Being/ # Intermediate transformations +├── Moment/ # Essential parts constituting the whole (experimental) +├── Final/ # Destinations (complete existence) +├── Reason/ # Tool sets enabling existence +├── Semantic/ # Domain vocabulary (what CAN exist) +├── Exception/ # Domain exceptions (why existence fails) +└── Module/ # DI configuration ``` -## Why Being Over Doing +## Side Effects + +Side effects are completed inside the constructor, delegated to Reason. The object itself decides — no external orchestrator tells it what to do. This is the autonomy that OOP originally intended. + +Persistence and external communication are implementation details confined to Reason. Existence types are freed from database schemas and API constraints. + +## Moment (Experimental) -### Traditional (Doing) +> This is an evolving concept that may be refined based on practical experience. + +A Moment is an essential part constituting a Final — a realizable potential that becomes actuality through `be()`. Used in the **Diamond Metamorphosis** pattern where multiple parallel pipelines converge into a single Final. ```php -$patient = new Patient($temp, $hr); -if ($triageService->isEmergency($patient)) { - $patient->setStatus('emergency'); - $this->erService->assign($patient); +final readonly class PaymentCompleted implements MomentInterface +{ + public PaymentCapture $capture; + + public function __construct( + #[CardNumber] public string $cardNumber, + #[Amount] public int $amount, + #[Inject] PaymentGatewayInterface $gateway, + ) { + $this->capture = $gateway->authorize($cardNumber, $amount); + } + + public function be(): void + { + $this->capture->be(); // Realize the potential + } } ``` -Problems: -- Patient can exist in invalid state -- Status can be changed at any time -- `erService->assign()` can be called on any patient +The Final calls `be()` on its Moments in its own constructor — this is not external orchestration but **Doing for Being**: the Final realizing its parts in order to bring itself into existence. -### Be Framework (Being) +```php +final readonly class OrderConfirmed +{ + public function __construct( + #[Inject] public InventoryReserved $inventory, + #[Inject] public PaymentCompleted $payment, + #[Inject] public ShippingArranged $shipping, + ) { + // Final's self-determination: realizing parts to bring itself into existence + $this->inventory->be(); + $this->payment->be(); + $this->shipping->be(); + } +} +``` + +## Type IS Capability + +Different types have different methods. Type determines what actions are possible: ```php -$patient = new PatientArrival($temp, $hr); -$result = $becoming($patient); -$result->assignER(); // Type-safe: only possible for EmergencyCase +// EmergencyCase has assignER() +// ObservationCase has assignWaitingArea() +$result->assignER(); // Only possible for EmergencyCase — compile-time safe ``` -Benefits: -- Non-survivable states cannot exist -- Type IS the status (immutable) -- Capabilities belong to existence +You cannot assign an ER room to an observation patient. The type system enforces this. ## Documentation - English: https://be-framework.github.io/manuals/1.0/en/ - Japanese: https://be-framework.github.io/manuals/1.0/ja/ - Repository: https://github.com/be-framework/be-framework +- App Skeleton: https://github.com/be-framework/app +- Demos: https://github.com/be-framework/demos +- Claude Code Skills: https://github.com/be-framework/skills diff --git a/llms.txt b/llms.txt index 92689f6..3a6643b 100644 --- a/llms.txt +++ b/llms.txt @@ -1,25 +1,40 @@ # Be Framework -> Objects don't DO things—they BECOME things. +> Objects don't DO things — they BECOME things. -Be Framework is a PHP framework for ontological programming where transformation (metamorphosis) replaces procedural action. +Be Framework is a PHP framework for ontological programming. Instead of telling objects what to do, you declare what can exist. Types are existence conditions — invalid states are structurally inexpressible. Metamorphosis replaces procedural action. + +## Core Concepts + +- **Immanence + Transcendence → New Immanence**: Every transformation follows this formula. `#[Input]` carries what the object is; `#[Inject]` brings external power; public properties express the new existence. +- **Self-Organization**: Objects declare their own destiny via `#[Be]`. No external orchestrators or service layers needed. +- **Semantic Variables**: Variable names carry meaning and constraints. `$email` must be a valid email to exist. Define once, automatically applied everywhere. +- **Reason Layer**: Gathers the complete tool set for an existence to come into being, into a single object. +- **Type IS Capability**: Different types have different methods. An `EmergencyCase` can `assignER()`; an `ObservationCase` cannot. ## Documentation -- [Overview](https://be-framework.github.io/manuals/1.0/en/01-overview.html): Framework philosophy +- [Overview](https://be-framework.github.io/manuals/1.0/en/01-overview.html): From Doing to Being - [Getting Started](https://be-framework.github.io/manuals/1.0/en/getting-started.html): Quick start guide - [Tutorial](https://be-framework.github.io/manuals/1.0/en/tutorial.html): Emergency Triage example -- [Input Classes](https://be-framework.github.io/manuals/1.0/en/02-input-classes.html): Starting points +- [Input Classes](https://be-framework.github.io/manuals/1.0/en/02-input-classes.html): Starting points (pure immanence) - [Being Classes](https://be-framework.github.io/manuals/1.0/en/03-being-classes.html): Intermediate transformations -- [Final Objects](https://be-framework.github.io/manuals/1.0/en/04-final-objects.html): Destinations -- [Semantic Variables](https://be-framework.github.io/manuals/1.0/en/06-semantic-variables.html): Domain validation -- [Type-Driven Metamorphosis](https://be-framework.github.io/manuals/1.0/en/07-type-driven-metamorphosis.html): Branching patterns -- [Reason Layer](https://be-framework.github.io/manuals/1.0/en/08-reason-layer.html): Transcendence +- [Final Objects](https://be-framework.github.io/manuals/1.0/en/04-final-objects.html): Destinations and $been +- [Becoming](https://be-framework.github.io/manuals/1.0/en/04a-becoming.html): Triggering metamorphosis +- [Metamorphosis](https://be-framework.github.io/manuals/1.0/en/05-metamorphosis.html): Patterns — linear, branching, nested +- [Semantic Variables](https://be-framework.github.io/manuals/1.0/en/06-semantic-variables.html): Names as meaning and constraints +- [Reason Layer](https://be-framework.github.io/manuals/1.0/en/08-reason-layer.html): Raison d'etre of existence +- [Semantic Exceptions](https://be-framework.github.io/manuals/1.0/en/09-error-handling.html): Meaningful failures +- [Demos](https://be-framework.github.io/manuals/1.0/en/demos.html): Working code examples +- [FAQ](https://be-framework.github.io/manuals/1.0/en/faq.html): Common questions ## Full Documentation -For detailed API and examples, see [llms-full.txt](https://be-framework.github.io/llms-full.txt) +For complete API reference and code examples: [llms-full.txt](https://be-framework.github.io/llms-full.txt) ## Repository -https://github.com/be-framework/be-framework +- Framework: https://github.com/be-framework/be-framework +- App Skeleton: https://github.com/be-framework/app +- Demos: https://github.com/be-framework/demos +- Claude Code Skills: https://github.com/be-framework/skills From 4c05ae35f9ed0830f5e18e036b2c1d09f0129f82 Mon Sep 17 00:00:00 2001 From: Akihito Koriyama Date: Thu, 19 Mar 2026 23:27:58 +0900 Subject: [PATCH 14/16] Refactor chapters 1-3, 5 and CLAUDE.md ja/en Align overview, input classes, being classes, and metamorphosis chapters with refined terminology and tone. --- CLAUDE.md | 125 ++++++++------------ manuals/1.0/en/01-overview.md | 8 +- manuals/1.0/en/02-input-classes.md | 14 +-- manuals/1.0/en/03-being-classes.md | 101 ++++------------ manuals/1.0/en/05-metamorphosis-patterns.md | 22 +++- manuals/1.0/ja/01-overview.md | 18 +-- manuals/1.0/ja/02-input-classes.md | 30 ++--- manuals/1.0/ja/03-being-classes.md | 125 ++++++-------------- manuals/1.0/ja/05-metamorphosis-patterns.md | 22 +++- 9 files changed, 179 insertions(+), 286 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 0c9f45c..7ac83c3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,82 +4,59 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Project Overview -This is a Jekyll-based documentation website for the Be Framework, a PHP framework focused on ontological programming concepts. The site serves as the manual and documentation hub, supporting both English and Japanese languages. +Jekyll-based documentation website for the Be Framework, a PHP framework focused on ontological programming. Supports English and Japanese. ## Development Commands -### Local Development Server ```bash -./bin/serve.sh +./bin/serve.sh # Start Jekyll dev server via Docker on port 4000 +docker compose up # Same as above +bundle exec jekyll serve # If Ruby/Jekyll installed locally ``` -This starts a Docker container running Jekyll server on port 4000. - -### Alternative Development Methods -- **Docker Compose**: `docker compose up` (same as serve.sh) -- **Bundle/Jekyll**: `bundle exec jekyll serve` (if working locally with Ruby/Jekyll installed) - -### Build Process -Jekyll automatically builds the site when serving. The generated site is output to `_site/` directory. - -## Architecture & Structure - -### Core Structure -- **Jekyll Configuration**: `_config.yml` - Main Jekyll configuration -- **Content**: `manuals/1.0/` - Documentation content organized by version and language -- **Layouts**: `_layouts/` - Jekyll templates for different page types -- **Includes**: `_includes/` - Reusable template components, especially navigation -- **Assets**: Static assets are in root and `_site/` after build - -### Multi-language Support -- **English**: `/manuals/1.0/en/` -- **Japanese**: `/manuals/1.0/ja/` -- Navigation templates automatically switch between languages -- Layout templates: `docs-en.html` and `docs-ja.html` - -### Manual Structure -The Be Framework manual is organized in 12 chapters: -1. Overview - Introduction to being-oriented programming -2. Input Classes - Starting points of transformation -3. Being Classes - Intermediate transformations -4. Final Objects - Transformation destinations -5. Metamorphosis Patterns - Transformation patterns -6. Semantic Variables - Domain validation and type safety -7. Type-Driven Metamorphosis - Self-determining objects -8. Reason Layer - Ontological capabilities -9. Error Handling - Semantic exceptions -10. Philosophy Behind - Framework philosophy -11. Semantic Logging - Metamorphosis tracking -12. From Doing to Being - Paradigm overview - -### Navigation System -- Main navigation is defined in `_includes/manuals/1.0/en/contents.html` (and ja version) -- Navigation automatically highlights current page -- Language switching functionality built into templates -- Table of contents generated dynamically for articles - -### Jekyll Setup -- Uses `minima` theme -- Rouge syntax highlighter -- Kramdown markdown processor -- GitHub Pages compatible configuration -- Docker-based development environment - -## Key Files for Content Updates - -### Adding New Manual Pages -1. Create markdown file in appropriate language directory (`manuals/1.0/en/` or `/ja/`) -2. Update navigation in `_includes/manuals/1.0/[lang]/contents.html` -3. Add appropriate frontmatter with layout (`docs-en` or `docs-ja`) - -### Modifying Site Structure -- Main site configuration: `_config.yml` -- Page layouts: `_layouts/` -- Reusable components: `_includes/` -- Styling: Source styles live under your theme or `assets/` (do not edit `_site/`; it is build output) - -### Content Guidelines -- Manual pages use specific Jekyll layouts (`docs-en`, `docs-ja`) -- Index page uses special `index` layout -- Navigation must be manually updated when adding pages -- Consistent frontmatter required for proper rendering -- Use page permalinks (`.html`) for cross-links, e.g., `./02-input-classes.html` (avoid linking to `.md`) \ No newline at end of file + +Jekyll builds to `_site/` automatically. Never edit files in `_site/` — it is build output. + +## Architecture + +### Page Rendering Pipeline + +1. Markdown files in `manuals/1.0/{en,ja}/` with frontmatter +2. Layout templates in `_layouts/` (`docs-en.html`, `docs-ja.html`, `index.html`, `index_ja.html`) +3. Shared header/footer in `_includes/manuals/1.0/` (header, footer, language-specific contents) +4. `_plugins/sidebar_generator.rb` auto-generates sidebar navigation from pages with `category: Manual` +5. `_includes/manuals/1.0/{en,ja}/contents.html` renders the sidebar using Liquid, iterating `site.pages` + +### Language Switching + +Language toggle works by replacing `/en/` ↔ `/ja/` in the page's permalink. For this to work, English and Japanese pages must have **mirrored permalink paths** — e.g., `/manuals/1.0/en/01-overview.html` and `/manuals/1.0/ja/01-overview.html`. + +### Required Page Frontmatter + +Every manual page must include: + +```yaml +--- +layout: docs-en # or docs-ja +title: "1. Overview" +category: Manual +permalink: /manuals/1.0/en/01-overview.html +--- +``` + +- `layout` determines language-specific template and sidebar +- `category: Manual` is required for sidebar inclusion +- `permalink` must follow the pattern `/manuals/1.0/{lang}/{filename}.html` +- Pages under `convention/` or with `sidebar: false` are excluded from sidebar + +### Adding a New Manual Page + +1. Create `.md` file in `manuals/1.0/en/` and `manuals/1.0/ja/` with proper frontmatter +2. File naming: `NN-slug.md` (number prefix controls sort order in sidebar) +3. Navigation sidebar is auto-generated — no manual nav update needed +4. Cross-link to other pages using `.html` extensions (not `.md`): `./02-input-classes.html` + +### Other Files + +- `llms.txt` / `llms-full.txt` — LLM-friendly project documentation (linked from header as "LLMs") +- `_plugins/sidebar_data.rb` / `sidebar_generator.rb` — Jekyll generators for sidebar data +- `Dockerfile` — `jekyll/jekyll:pages` image with webrick diff --git a/manuals/1.0/en/01-overview.md b/manuals/1.0/en/01-overview.md index 6f897ec..9b8f331 100644 --- a/manuals/1.0/en/01-overview.md +++ b/manuals/1.0/en/01-overview.md @@ -44,8 +44,8 @@ $user->notify(); Be Framework focuses on BEING (what to be): ```php -$rawData = new UserInput($_POST); -$validatedUser = new ValidatedUser($rawData); +$userInput = new UserInput($name, $email); +$validatedUser = new ValidatedUser($userInput); $savedUser = new SavedUser($validatedUser); ``` @@ -77,13 +77,13 @@ function archiveUser(DeletedUser $user) { } Each type is not just data, but expresses a specific state of the object. In other words, the temporal change of the object is represented by the type, and you can only do what is possible at that time. For example, you cannot order a non-existent object to be deleted. -## Why Not a "Controller"? (Wu Wei / Non-doing) +## Why Not a "Controller"? The "Controller" in traditional MVC frameworks aims for "control and domination" as its name suggests. However, as systems become complex, this "approach of trying to control everything" becomes difficult. A Controller has "omnipotent freedom" to access all models and components, but having no constraints means implicitly bearing "infinite responsibility" to control and maintain consistency for every procedure in the system by itself. -Be Framework adopts a different approach, incorporating the philosophy of "Wu Wei" (Non-doing) from Eastern philosophy. Rather than operations creating the target data, simple input objects like seeds meet other objects, grow naturally, and "transform themselves (Metamorphosis)" into the target final objects. +Be Framework adopts a different approach. Rather than operations creating the target data, simple input objects like seeds meet other objects, grow naturally, and "transform themselves (Metamorphosis)" into the target final objects. ### Commander to Gardener: * The Commander orders subordinates (objects) to "Move!". But it is impossible to keep ordering all complex autonomous movements. diff --git a/manuals/1.0/en/02-input-classes.md b/manuals/1.0/en/02-input-classes.md index 2078e8c..5a96c88 100644 --- a/manuals/1.0/en/02-input-classes.md +++ b/manuals/1.0/en/02-input-classes.md @@ -20,7 +20,7 @@ This contains only the elements that the object itself possesses, with no extern ## Basic Structure ```php -#[Be(UserProfile::class)] // Destiny of Metamorphosis +#[Be(ValidatedUser::class)] // Destiny of Metamorphosis final readonly class UserInput { public function __construct( @@ -34,9 +34,11 @@ final readonly class UserInput **Pure Identity**: Input Classes contain only *what the object fundamentally is*—no external dependencies or complex logic. +**Use Case Origin**: Every use case has its own Input Class. + **Destination (Object's Destiny)**: The `#[Be()]` attribute declares what this input will become. -**Read-only Properties**: All data is immutable, representing a fixed identity that transforms rather than mutates. +**Read-only Properties**: All properties are `readonly`. The values of the Input Class are never modified. ## Examples @@ -65,14 +67,6 @@ final readonly class PaymentInput } ``` -## The Role of Immanence - -In Input Classes, everything is **Immanence**. There is no **Transcendence (transcendent power)** here. Transcendence explains powers provided from the outside that cannot be realized by oneself, and they appear later in **Being Classes**. - -For example, the `UserInput` class holds only raw data like email address and name. The power to validate if this email is valid, the power to save to the database, the power to send notifications—these are all Transcendence and do not exist in the Input Class. The Input Class simply declares "I am this kind of data". - -Input Classes are the starting point of transformation. They represent the first form that meets something beyond itself and changes into something new. - --- The Input Class meets the outside world and begins transformation. We will see that process in [Being Classes](./03-being-classes.html) ➡️ diff --git a/manuals/1.0/en/03-being-classes.md b/manuals/1.0/en/03-being-classes.md index fb92f6f..7df8931 100644 --- a/manuals/1.0/en/03-being-classes.md +++ b/manuals/1.0/en/03-being-classes.md @@ -13,42 +13,18 @@ permalink: /manuals/1.0/en/03-being-classes.html ## Immanence and Transcendence -Being Classes are where metamorphosis actually happens. +If Input Classes are the "Beginning", Being Classes express the "Transformed Being". -The properties that the object itself possesses (**Immanence**) meet the powers provided from the outside (**Transcendence**), and a new Being is born. - -For example, the email address and name (Immanence) held by `UserInput` meet the email validation service or formatter (Transcendence), and a new being called "Validated User Profile" is born. The original data remains unchanged, but through the encounter with the transcendent power of validation that it does not possess, a new existence arises. - -If Input Classes are the "Beginning", Being Classes express the "Moment of Change". - -## Objects as Temporal Beings - -In Be Framework, objects are not treated as static data structures, but as "Life" living in time. - -### Lifecycle: Birth, Life, and "Becoming the self you want to be" - -1. **Birth (Constructor)**: - * The constructor is where objects are born. Here, Immanence and Transcendence meet, and new Immanence is born. - * The moment it is born, the object's identity and state are determined and become Immutable. -2. **Life (Being)**: - * The object exposes its "form as it should be" to the world as `public readonly` properties. But no one touches those properties except its future self. - * This state is the crystallization of the encounter between Immanence and Transcendence. -3. **Becoming the self you want to be**: - * All transformations are journeys to become the final "Self you want to be (Final Object)". - * The Transcendence encountered influences the new Immanence and disappears. Like a childhood friend, they shape me and become part of me, but as a **temporal being only at that moment**, they are no longer there. - * The life of an object in Be Framework exists for this self-realization (Entelechy). - -> "Becoming the self you want to be" -> Objects are reborn into the self they want to be, according to their own will (type definition). Code is the story of this "Self-realization". +The public properties of the Input Class are inherited by the Being Class constructor. These inherited values are called **Immanence**—they preserve identity through transformation. In the constructor, external powers—**Transcendence**—are injected and transform the Immanence. ## Basic Structure ```php -final readonly class UserProfile +final readonly class ValidatedUser { public string $displayName; public bool $isValid; - + public function __construct( #[Input] string $name, // Immanence #[Input] string $email, // Immanence @@ -61,25 +37,29 @@ final readonly class UserProfile } ``` -## Metamorphosis Pattern +## Objects as Temporal Beings + +In Be Framework, objects are not treated as static data structures, but as temporal beings that exist only within a specific moment in time. + +### Birth (Constructor) + +The constructor is where objects are born. All Being Classes follow the same flow of transformation: -All Being Classes follow the same flow of transformation: +**Immanence** (`#[Input]`) + **Transcendence** (`#[Inject]`) → **New Immanence** -Immanence (`#[Input]`) + Transcendence (`#[Inject]`) → New Immanence +Immanence meets Transcendence, the logic of transformation takes effect, and new Immanence is born through property assignment. The moment it is born, the object's identity and state are determined and become Immutable. -It's like cooking. By adding fire and seasoning (Transcendence) to ingredients (Immanence), a dish (New Immanence) is created. Flour alone does not become bread, but with the help of yeast and an oven, it becomes bread. Even if the ingredients are the same, it becomes a completely new existence. +### Life (Being) -- **Immanent Factor**: What the object inherits from its previous form -- **Transcendent Factor**: External capabilities and context provided by the world -- **New Immanence**: Transformed existence born from this interaction +The object exposes its "form as it should be" to the world as `public readonly` properties. But no one touches those properties—the object vanishes shortly after birth, making way for the next. -This pattern is found everywhere in the natural world. A seed (Immanence) meets soil, water, and sun (Transcendence) to become a flower. A student (Immanence) meets a teacher and textbooks (Transcendence) to become an expert. All growth, all learning, all change follows this pattern. Be Framework expresses this universal law of transformation in code. +### Becoming the Self You Want to Be -It is the same in the world of programming. `$cartItems` (Immanence) meets tax calculation service (Transcendence) to become a billing amount. `$zipCode` (Immanence) meets address search API (Transcendence) to become a complete address. `$rawImage` (Immanence) meets image processing engine (Transcendence) to become a thumbnail. Data cannot change on its own. It borrows external power to finally become a new existence. +All transformations are journeys to become the final "self you want to be, the self you are meant to be (Final Object)". -## Entelechy - Becoming the self you want to be +The Transcendence encountered influences the new Immanence and disappears. Like a childhood friend, they shape me and become part of me, but as a temporal being only at that moment, they are no longer there. -The constructor is a special place where a new self is born. To become the self it should be, Immanence meets Transcendence given by the world (which it does not possess itself), and the logic of transformation works. +## Example of Transformation ```php final readonly class OrderCalculation @@ -87,7 +67,7 @@ final readonly class OrderCalculation public Money $subtotal; public Money $tax; public Money $total; - + public function __construct( #[Input] array $items, // Immanence #[Input] string $currency, // Immanence @@ -101,48 +81,15 @@ final readonly class OrderCalculation } ``` -1. Properties inherited from the previous class become constructor arguments and meet injected external capabilities. -2. They interact, and transformation logic works. -3. A new existence is born by assigning properties. - -Entelechy (entelecheia) is a philosophical concept proposed by Aristotle, meaning "having the end within itself". An acorn is born to become an oak tree, and an egg exists to become a bird. Each holds the "self it wants to be" within. - -In Be Framework, this transformation process in the constructor is exactly the realization of Entelechy. `OrderCalculation` wants to become a calculated order. `ValidatedUser` wants to become a validated user. Each class becomes the "self it wants to be" in the constructor. In Be Framework, we think centering on BEING (existence), not DOING (action). - -It's the same in life. You read books to become a "person with deep insight", and practice instruments to become a "person who moves hearts with music". Action is the means, and existence is the purpose. Focusing on "What you want to become" rather than "What you do"—Be Framework expresses this way of thinking in code. +`OrderCalculation` wants to become a calculated order. `ValidatedUser` wants to become a validated user. Each class becomes the "self it wants to be" in the constructor. In Be Framework, we think centering on BEING (existence), not DOING (action). -## Bridge to Final Object +## Reflection on Transformation -Being classes often serve as bridges, preparing data for final transformation: - -```php -#[Be([SuccessfulOrder::class, FailedOrder::class])] // Multiple destinies -final readonly class OrderValidation -{ - public bool $isValid; - public array $errors; - public SuccessfulOrder|FailedOrder $being; // Being property - - public function __construct( - #[Input] Money $total, // Immanence - #[Input] CreditCard $card, // Immanence - #[Inject] PaymentGateway $gateway // Transcendence - ) { - $result = $gateway->validate($card, $total); - $this->isValid = $result->isValid(); - $this->errors = $result->getErrors(); - - // Self-determination of destiny - $this->being = $this->isValid - ? new SuccessfulOrder($total, $card) - : new FailedOrder($this->errors); - } -} -``` +Immanence alone cannot change. No matter how rich the data, it cannot become a new existence by its own power. Transformation always requires an encounter with Transcendence—a power outside itself. And the Transcendence that was encountered changes the Immanence and then disappears. This pattern of "meeting, changing, and vanishing" is not limited to code. Flour meets yeast and heat to become bread; grapes meet yeast and time to become wine; a seed meets soil, water, and light to become a flower. Transformation in every domain follows this pattern. ## Natural Flow -Being classes do not "do" anything. By meeting what they have (Immanence) and power given from outside (Transcendence), they naturally transform into the form they should be. This is the same as Laozi's teaching at the beginning, "The Way constantly does nothing, yet there is nothing it does not do"—everything is accomplished in the natural flow without forcing power. It does not change something else, but changes itself. +Being classes do not "do" anything. By the meeting of what they have (Immanence) and powers given from outside (Transcendence), they naturally transform into the form they should be. Nothing orchestrates this flow. Each object is simply passed to the next. --- diff --git a/manuals/1.0/en/05-metamorphosis-patterns.md b/manuals/1.0/en/05-metamorphosis-patterns.md index 903f2b5..828b6c2 100644 --- a/manuals/1.0/en/05-metamorphosis-patterns.md +++ b/manuals/1.0/en/05-metamorphosis-patterns.md @@ -62,6 +62,26 @@ final readonly class ApplicationReview } ``` +## Type-Based Continuation + +Among the candidate classes specified in `#[Be()]`, the framework automatically selects the one whose constructor `#[Input]` parameter matches the type of a public property on the current object: + +```php +// If ApplicationReview's property is of type ApprovedApplication, +// this class is automatically selected because #[Input] type matches +final readonly class ApprovalNotification +{ + public function __construct( + #[Input] ApprovedApplication $application, + #[Inject] Mailer $mailer + ) { + $mailer->send($application->getEmail(), 'Approved!'); + } +} +``` + +`$being` is a conventional property name often used for this self-determination pattern, but it is not a name required by the framework. Any public property participates in matching. + ## Self-Organizing Pipelines Like UNIX pipes that combine simple commands to create powerful systems, Be Framework combines typed objects to create natural transformation flows. @@ -71,7 +91,7 @@ Like UNIX pipes that combine simple commands to create powerful systems, Be Fram cat access.log | grep "404" | awk '{print $7}' | sort | uniq -c ``` -In UNIX, the shell controls the pipeline. In Be Framework, objects declare their own destiny with `#[Be()]`. No external control needed. No controllers, no orchestrators. +In UNIX, the shell controls the pipeline. In Be Framework, objects declare their own destiny with `#[Be()]`. There is no external control such as controllers or orchestrators. Heraclitus said "the flowing is the river." Just as it is not that a river flows, but that the flowing itself is the river, domains in the Be Framework are temporal existence that never rest until they reach their end. diff --git a/manuals/1.0/ja/01-overview.md b/manuals/1.0/ja/01-overview.md index ce1be43..61a0f0a 100644 --- a/manuals/1.0/ja/01-overview.md +++ b/manuals/1.0/ja/01-overview.md @@ -7,10 +7,6 @@ permalink: /manuals/1.0/ja/01-overview.html # 概要 -> 「なりたい自分になる (Becoming the self you want to be)」 -> Be Frameworkとは、オブジェクトが自らの意思で、なりたい自分へと変容するためのフレームワークです。 - -マルセル・プルーストは言いました。 > 真の航海とは、新しい風景を探すことではなく、新しい目を持つことである。 > >   —マルセル・プルースト『囚われの女』(À la recherche du temps perdu 第5巻)1923年 @@ -28,10 +24,8 @@ $user->delete(); $activeUser = User::find($id); $deletedUser = new DeletedUser($activeUser); ``` - -「`DeletedUser`」って何?と思いましたか? - -実はこの疑問が、プログラミングの新しい世界への入り口です。これまで考えてもみなかった方法で、プログラミングを考えてみましょう。 +DeletedUserって何?と思うかもしれません。 +これまで考えてもみなかった方法で、プログラミングを考えてみましょう。 ## 『何をするか』から『何であるか』へ @@ -44,8 +38,8 @@ $user->notify(); BeフレームワークはBEING(何であるか)に着目します: ```php -$rawData = new UserInput($_POST); -$validatedUser = new ValidatedUser($rawData); +$userInput = new UserInput($name, $email); +$validatedUser = new ValidatedUser($userInput); $savedUser = new SavedUser($validatedUser); ``` @@ -77,13 +71,13 @@ function archiveUser(DeletedUser $user) { } 各型はただのデータではなく、オブジェクトの特定の状態を表現しています。つまり、オブジェクトの時間的な変化が型で表されていて、その時に可能なことだけが行えます。例えば、存在しないオブジェクトに削除を命じることはできません。 -## なぜ「コントローラー」ではないのか? (Wu Wei / 無為自然) +## なぜ「コントローラー」ではないのか? 従来のMVCフレームワークにおける「コントローラー (Controller)」は、その名の通り「制御・支配」を目的としています。 しかし、システムが複雑になるにつれて、この「全てを支配しようとするアプローチ」は困難になります。 コントローラーは全てのモデルやコンポーネントに無制限にアクセスできる「全能の自由」を持っていますが、制約がないということは、逆に言えばシステム内のあらゆる手続きについて、自分自身で制御し整合性を保つという「無限の責任」を負うことを意味します。 -Be Frameworkは、東洋哲学の「無為自然 (Wu Wei)」の思想を取り入れた異なるアプローチを採ります。 操作が目的のデータをつくり出すのではなく、種子のような単純な入力オブジェクトが他のオブジェクトと出会い、自然に成長し、目的の最終オブジェクトへと「自ら変容(Metamorphosis)」していきます。 +Be Frameworkは異なるアプローチを採ります。操作が目的のデータをつくり出すのではなく、種子のような単純な入力オブジェクトが他のオブジェクトと出会い、自然に成長し、目的の最終オブジェクトへと「自ら変容(Metamorphosis)」していきます。 ### Commander (司令官) から Gardener (庭師) へ: * 司令官は、部下(オブジェクト)に「動け」と命令します。しかし、複雑な自律的な動きを全て命令し続けることは不可能です。 diff --git a/manuals/1.0/ja/02-input-classes.md b/manuals/1.0/ja/02-input-classes.md index d202c5a..9826447 100644 --- a/manuals/1.0/ja/02-input-classes.md +++ b/manuals/1.0/ja/02-input-classes.md @@ -15,17 +15,17 @@ permalink: /manuals/1.0/ja/02-input-classes.html 入力クラスは、Beフレームワークにおけるすべての変容の出発点です。 -ここにはオブジェクト自身が持つ要素だけが含まれ、外部依存がありません。いわばオブジェクトのアイデンティティです。オブジェクトの内側にあるものなので、これを**内在的性質、イマナンス(Immanence)**と呼びます。 +ここにはオブジェクト自身が持つ要素だけが含まれ、外部依存がありません。いわばオブジェクトのアイデンティティです。オブジェクトの内側にあるものなので、これを**内在(Immanence)**と呼びます。 ## 基本構造 ```php -#[Be(UserProfile::class)] // 変容の運命 +#[Be(ValidatedUser::class)] // 変容の運命 final readonly class UserInput { public function __construct( - public string $name, // 内在的 - public string $email // 内在的 + public string $name, // 内在 + public string $email // 内在 ) {} } ``` @@ -34,9 +34,11 @@ final readonly class UserInput **純粋なアイデンティティ**: 入力クラスはオブジェクトが根本的に*何であるか*のみを含みます—外部依存関係や複雑なロジックはありません。 +**ユースケースの起点**: すべてのユースケースは固有の入力クラスを持ちます。 + **変容先(オブジェクトの運命)**: `#[Be()]`属性は、この入力が何になるかを宣言します。 -**読み取り専用プロパティ**: すべてのデータは不変であり、変異ではなく変容する固定されたアイデンティティを表します。 +**読み取り専用プロパティ**: すべてのプロパティは `readonly` です。入力クラスの値は変更されません。 ## 例 @@ -46,8 +48,8 @@ final readonly class UserInput final readonly class OrderInput { public function __construct( - public array $items, // 内在的 - public string $currency // 内在的 + public array $items, // 内在 + public string $currency // 内在 ) {} } ``` @@ -58,21 +60,13 @@ final readonly class OrderInput final readonly class PaymentInput { public function __construct( - public Money $amount, // 内在的 - public CreditCard $card, // 内在的 - public Address $billing // 内在的 + public Money $amount, // 内在 + public CreditCard $card, // 内在 + public Address $billing // 内在 ) {} } ``` -## イマナンスの役割 - -入力クラスでは、すべてが**イマナンス**です。ここには**トランセンデンス(Transcendence/超越的な力)**はありません。トランセンデンスは外部から提供される、自分だけでは実現不可能な力であり、それらは後で**存在クラス(Being クラス)**において現れます。 - -例えば、`UserInput`クラスはメールアドレスと名前という素のデータだけを持ちます。このメールアドレスが有効かどうかを検証する力、データベースに保存する力、通知を送る力——これらはすべてトランセンデンスであり、入力クラスには存在しません。入力クラスはただ「私はこういうデータです」と宣言するだけです。 - -入力クラスは変容の出発点です。自己を超えたものと出会って、新しい何かへと変わっていく最初の姿を表します。 - --- 入力クラスが外の世界と出会い、変容を始めます。その過程を[存在クラス](./03-being-classes.html)で見ていきます ➡️ diff --git a/manuals/1.0/ja/03-being-classes.md b/manuals/1.0/ja/03-being-classes.md index be1524e..9eafe17 100644 --- a/manuals/1.0/ja/03-being-classes.md +++ b/manuals/1.0/ja/03-being-classes.md @@ -8,78 +8,58 @@ permalink: /manuals/1.0/ja/03-being-classes.html # 存在クラス > 「道常無為而無不為」 -> +> > —道は常に無為にして、而も為さざることなし(老子『道徳経』第三十七章 紀元前6世紀) ## 内在と超越 -存在クラスは変容が実際に起こる場所です。 +入力クラスが「始まり」なら、存在クラスは「変容した存在」を表現します。 -オブジェクト自身が持つ性質(内在的性質(イマナンス))と、外部から提供される力(超越的な力(トランセンデンス))が出会い、次の新しい存在が生まれます。 - -例えば、`UserInput`が持つメールアドレスと名前(イマナンス)が、メール検証サービスやフォーマッター(トランセンデンス)と出会うことで、「検証済みのユーザープロフィール」という新しい存在が生まれます。元のデータは不変のまま、検証という自分にはない超越的な力との出会いを通じて、新しい存在が立ち上がります。 - -入力クラスが「始まり」なら、存在クラスは「変わる瞬間」を表現します。 - -## 時間的存在としてのオブジェクト (Temporal Being) - -Be Frameworkにおいて、オブジェクトは静的なデータ構造ではなく、時間の中を生きる「生命」として扱われます。 - -### ライフサイクル:誕生、生、そして「なりたい自分になる」 - -1. **誕生 (Birth/Constructor)**: - * コンストラクタは、オブジェクトが生まれる場所です。ここで内在と超越が出会い、新しい内在が生まれます。 - * 生まれた瞬間、そのオブジェクトのアイデンティティと状態は確定し、不変(Immutable)となります。 -2. **生 (Life/Being)**: - * オブジェクトは `public readonly` プロパティとして、その「あるべき姿」を世界に晒します。しかしそのプロパティを触るものは未来の自分以外いません。 - * この状態は、内在と超越の出会いが結晶化したものです。 -3. **なりたい自分になる (Becoming the self you want to be)**: - * すべての変容は、最終的な「なりたい自分(Final Object)」になるための旅です。 - * 出会った超越は、新しい内在(Immanence)に影響を与えて消滅します。幼少期の友人のように、私を形作り私の一部にはなりますが、その時だけの時間的存在として、もうそこにはいないのです。 - * Be Frameworkにおけるオブジェクトの生涯は、この自己実現(Entelechy)のためにあります。 - -> "Becoming the self you want to be" -> オブジェクトは、自らの意思(型定義)に従って、なりたい自分へと生まれ変わります。コードはこの「自己実現」の物語です。 +入力クラスのpublicプロパティが存在クラスのコンストラクタに引き継がれます。その引き継いだ値は**内在(Immanence)** と呼ばれます。変容しながらアイデンティティを保ちます。コンストラクタでは外部から提供される力—**超越(Transcendence)**がインジェクトされ**内在**を変容します。 ## 基本構造 ```php -final readonly class UserProfile +final readonly class ValidatedUser { public string $displayName; public bool $isValid; - + public function __construct( - #[Input] string $name, // 内在的 - #[Input] string $email, // 内在的 - #[Inject] NameFormatter $formatter, // 超越的 - #[Inject] EmailValidator $validator // 超越的 + #[Input] string $name, // 内在 + #[Input] string $email, // 内在 + #[Inject] NameFormatter $formatter, // 超越 + #[Inject] EmailValidator $validator // 超越 ) { - $this->displayName = $formatter->format($name); // 新しい内在的 - $this->isValid = $validator->validate($email); // 新しい内在的 + $this->displayName = $formatter->format($name); // 新しい内在 + $this->isValid = $validator->validate($email); // 新しい内在 } } ``` -## 変容パターン +## 時間的存在としてのオブジェクト + +Be Frameworkにおいて、オブジェクトは静的なデータ構造ではなく、特定の時間の中でのみ存在する時間的存在として扱われます。 -すべての存在クラスは同じ変容の流れに従います: +### 誕生 -内在的性質 (`#[Input]`) + 超越的力 (`#[Inject]`) → 新しい内在的性質 +コンストラクタは、オブジェクトが生まれる場所です。すべての存在クラスは同じ変容の流れに従います: -まるで料理のようです。素材(内在的性質)に、火や調味料(超越的力)を加えることで、料理(新しい内在的性質)が生まれます。小麦粉はそれだけではパンになりませんが、イーストとオーブンの力を借りてパンになります。素材は同じでも、まったく新しい存在になるのです。 +**内在** (`#[Input]`) + **超越** (`#[Inject]`) → **新しい内在** -- **内在的要因**: オブジェクトが前の形態から継承するもの -- **超越的要因**: 世界によって提供される外部の能力と文脈 -- **新しい内在的**: この相互作用から生まれる変容した存在 +内在が超越と出会い、変容のロジックが働き、プロパティの代入によって新しい内在が生まれます。生まれた瞬間、そのオブジェクトのアイデンティティと状態は確定し、不変(Immutable)となります。 -このパターンは自然界のあらゆるところに見られます。種(内在)が土と水と太陽(超越)と出会って花になる。生徒(内在)が教師と教材(超越)と出会って専門家になる。すべての成長、すべての学び、すべての変化がこのパターンに従います。Be Frameworkは、この普遍的な変容の法則をコードで表現しているのです。 +### 生 -プログラムの世界でも同じです。`$cartItems`(内在)が税率計算サービス(超越)と出会って請求金額になる。`$zipCode`(内在)が住所検索API(超越)と出会って完全な住所になる。`$rawImage`(内在)が画像処理エンジン(超越)と出会ってサムネイルになる。データは自分だけでは変われません。外部の力を借りて、初めて新しい存在になれるのです。 +オブジェクトは `public readonly` プロパティとして、その「あるべき姿」を世界に晒します。しかしそのプロパティを触るものはいません。生まれた直後に次のオブジェクトのために消滅するからです。 -## エンテレケイア - なりたい自分になる +### なりたい自分になる -コンストラクタは新しい自己が生まれる特別な場所です。なるべき自己になるために、内在的性質と、自らは持たないが世界から与えられる超越的な力が出会い、変容のロジックが働きます。 +すべての変容は、最終的な「なりたい自分、なるべき自分(Final Object)」になるための旅です。 + +出会った超越は、新しい内在に影響を与えて消滅します。幼少期の友人のように、私を形作り私の一部にはなりますが、その時だけの時間的存在として、もうそこにはいなくなります。 + +## 変容の例 ```php final readonly class OrderCalculation @@ -87,62 +67,29 @@ final readonly class OrderCalculation public Money $subtotal; public Money $tax; public Money $total; - + public function __construct( - #[Input] array $items, // 内在的 - #[Input] string $currency, // 内在的 - #[Inject] PriceCalculator $calculator, // 超越的 - #[Inject] TaxService $taxService // 超越的 + #[Input] array $items, // 内在 + #[Input] string $currency, // 内在 + #[Inject] PriceCalculator $calculator, // 超越 + #[Inject] TaxService $taxService // 超越 ) { $this->subtotal = $calculator->calculateSubtotal($items, $currency); $this->tax = $taxService->calculateTax($this->subtotal); - $this->total = $this->subtotal->add($this->tax); // 新しい内在的 + $this->total = $this->subtotal->add($this->tax); // 新しい内在 } } ``` -1. 前のクラスから受け継いだプロパティがコンストラクタの引数となって、注入された外部の能力と出会う。 -2. 相互に作用して変容のロジックが働く。 -3. プロパティの代入によって新しい存在が誕生する。 +`OrderCalculation`は計算された注文になりたい。`ValidatedUser`は検証済みユーザーになりたい。各クラスがコンストラクタで「なりたい自分」になるのです。Be Frameworkでは、動作(DOING)ではなく、存在(BEING)を中心に考えます。 -エンテレケイア(entelecheia)とは、アリストテレスが提唱した哲学概念で、「内に目的を持つ」という意味です。どんぐりは樫の木になるべく生まれ、卵は鳥になるべく存在します。それぞれが「なりたい自分」を内に秘めているのです。 +## 変容についての考察 -Be Frameworkでは、このコンストラクタでの変容過程がまさにエンテレケイアの実現です。`OrderCalculation`は計算された注文になりたい。`ValidatedUser`は検証済みユーザーになりたい。各クラスがコンストラクタで「なりたい自分」になるのです。Be Frameworkでは、動作(DOING)ではなく、存在(BEING)を中心に考えます。 - -人生でも同じです。本を読むのは「深い洞察を持つ人」になるため、楽器を練習するのは「音楽で人の心を動かす人」になるためです。動作は手段であり、存在こそが目的なのです。「何をするか」ではなく「何になりたいか」に焦点を合わせる—この考え方を、Be Frameworkはコードで表現しているのです。 - -## 最終オブジェクトへの橋渡し - -存在クラスはしばしば架け橋として機能し、最終変容のためのデータを準備します: - -```php -#[Be([SuccessfulOrder::class, FailedOrder::class])] // 複数の運命 -final readonly class OrderValidation -{ - public bool $isValid; - public array $errors; - public SuccessfulOrder|FailedOrder $being; // 存在プロパティ - - public function __construct( - #[Input] Money $total, // 内在的 - #[Input] CreditCard $card, // 内在的 - #[Inject] PaymentGateway $gateway // 超越的 - ) { - $result = $gateway->validate($card, $total); - $this->isValid = $result->isValid(); - $this->errors = $result->getErrors(); - - // 運命の自己決定 - $this->being = $this->isValid - ? new SuccessfulOrder($total, $card) - : new FailedOrder($this->errors); - } -} -``` +内在だけでは変われません。データがどれほど豊かでも、それ自身の力で新しい存在にはなれないのです。変容には必ず超越—自分の外にある力—との出会いが必要です。そして出会った超越は内在を変え、自らは消えていきます。この「出会い、変わり、消える」というパターンは、コードに限った話ではありません。小麦粉はイーストと熱に出会ってパンになり、ぶどうは酵母と時間に出会ってワインになり、種は土と水と光に出会って花になります。あらゆるドメインの変容がこのパターンに従います。 ## 自然な流れ -存在クラスは何かを「する」のではありません。自分が持つもの(イマナンス)と、外部から与えられる力(トランセンデンス)が出会うことで、自然にあるべき姿へと変容します。これは冒頭の老子の「道常無為而無不為」—無理に力を加えることなく、自然な流れの中ですべてが成し遂げられる—という教えと同じです。他の何かを変えるのではなく、自分自身が変わっていきます。 +存在クラスは何かを「する」のではありません。自分が持つもの(内在)と、外部から与えられる力(超越)が出会うことで、自然にあるべき姿へと変容します。この流れを指揮するものはいません。各オブジェクトはただ次の存在に渡されるだけです。 --- diff --git a/manuals/1.0/ja/05-metamorphosis-patterns.md b/manuals/1.0/ja/05-metamorphosis-patterns.md index cadfce0..4f6ad29 100644 --- a/manuals/1.0/ja/05-metamorphosis-patterns.md +++ b/manuals/1.0/ja/05-metamorphosis-patterns.md @@ -62,6 +62,26 @@ final readonly class ApplicationReview } ``` +## 型による継続 + +`#[Be()]`で指定された候補クラスの中から、現在のオブジェクトのpublicプロパティの型がコンストラクタの`#[Input]`引数にマッチするクラスが自動的に選択されます: + +```php +// ApplicationReviewのプロパティがApprovedApplication型なら +// #[Input]の型がマッチするこのクラスが自動的に選択される +final readonly class ApprovalNotification +{ + public function __construct( + #[Input] ApprovedApplication $application, + #[Inject] Mailer $mailer + ) { + $mailer->send($application->getEmail(), 'Approved!'); + } +} +``` + +`$being`はこの自己決定パターンでよく使われるプロパティ名のコンベンションですが、フレームワークが要求する名前ではありません。どのpublicプロパティでもマッチングの対象になります。 + ## 自己組織化パイプライン Unixパイプが単純なコマンドを組み合わせて強力なシステムを作るように、Beフレームワークは型付きオブジェクトを組み合わせて自然な変容の流れを作ります。 @@ -71,7 +91,7 @@ Unixパイプが単純なコマンドを組み合わせて強力なシステム cat access.log | grep "404" | awk '{print $7}' | sort | uniq -c ``` -Unixではshellがパイプを制御しますが、Beフレームワークではオブジェクト自身が`#[Be()]`で運命を宣言します。外部の制御は不要です。コントローラーもオーケストレーターもありません。 +Unixではshellがパイプを制御しますが、Beフレームワークではオブジェクト自身が`#[Be()]`で運命を宣言します。コントローラーもオーケストレーターといった、外部の制御が存在しません。 ヘラクレイトスは「流れているのが川だ」と言いました。川が流れるのではなく、流れそのものが川であるように、Beフレームワークのドメインは終端まで静止することがない時間的存在です。 From 3a687ae19f197c04c3f605af4e5428b5f7f8fe51 Mon Sep 17 00:00:00 2001 From: Akihito Koriyama Date: Fri, 20 Mar 2026 00:45:38 +0900 Subject: [PATCH 15/16] Fix chapter numbering to match index.md Revert title numbers for chapters 5 and 6 to match filenames and index.md. Remove number from Becoming chapter title (supplementary chapter between 4 and 5). --- manuals/1.0/en/04a-becoming.md | 2 +- manuals/1.0/en/05-metamorphosis-patterns.md | 2 +- manuals/1.0/en/06-semantic-variables.md | 2 +- manuals/1.0/ja/04a-becoming.md | 2 +- manuals/1.0/ja/05-metamorphosis-patterns.md | 2 +- manuals/1.0/ja/06-semantic-variables.md | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/manuals/1.0/en/04a-becoming.md b/manuals/1.0/en/04a-becoming.md index aa9100e..3fe0cad 100644 --- a/manuals/1.0/en/04a-becoming.md +++ b/manuals/1.0/en/04a-becoming.md @@ -1,6 +1,6 @@ --- layout: docs-en -title: "5. Becoming" +title: "Becoming" category: Manual permalink: /manuals/1.0/en/04a-becoming.html --- diff --git a/manuals/1.0/en/05-metamorphosis-patterns.md b/manuals/1.0/en/05-metamorphosis-patterns.md index 828b6c2..643dc6d 100644 --- a/manuals/1.0/en/05-metamorphosis-patterns.md +++ b/manuals/1.0/en/05-metamorphosis-patterns.md @@ -1,6 +1,6 @@ --- layout: docs-en -title: "6. Metamorphosis" +title: "5. Metamorphosis" category: Manual permalink: /manuals/1.0/en/05-metamorphosis.html --- diff --git a/manuals/1.0/en/06-semantic-variables.md b/manuals/1.0/en/06-semantic-variables.md index 585b7ac..5e61790 100644 --- a/manuals/1.0/en/06-semantic-variables.md +++ b/manuals/1.0/en/06-semantic-variables.md @@ -1,6 +1,6 @@ --- layout: docs-en -title: "7. Semantic Variables" +title: "6. Semantic Variables" category: Manual permalink: /manuals/1.0/en/06-semantic-variables.html --- diff --git a/manuals/1.0/ja/04a-becoming.md b/manuals/1.0/ja/04a-becoming.md index 0d7bed7..02f192a 100644 --- a/manuals/1.0/ja/04a-becoming.md +++ b/manuals/1.0/ja/04a-becoming.md @@ -1,6 +1,6 @@ --- layout: docs-ja -title: "5. 生成" +title: "生成" category: Manual permalink: /manuals/1.0/ja/04a-becoming.html --- diff --git a/manuals/1.0/ja/05-metamorphosis-patterns.md b/manuals/1.0/ja/05-metamorphosis-patterns.md index 4f6ad29..f14b650 100644 --- a/manuals/1.0/ja/05-metamorphosis-patterns.md +++ b/manuals/1.0/ja/05-metamorphosis-patterns.md @@ -1,6 +1,6 @@ --- layout: docs-ja -title: "6. 変容" +title: "5. 変容" category: Manual permalink: /manuals/1.0/ja/05-metamorphosis.html --- diff --git a/manuals/1.0/ja/06-semantic-variables.md b/manuals/1.0/ja/06-semantic-variables.md index 7616fc8..fd85134 100644 --- a/manuals/1.0/ja/06-semantic-variables.md +++ b/manuals/1.0/ja/06-semantic-variables.md @@ -1,6 +1,6 @@ --- layout: docs-ja -title: "7. 意味変数" +title: "6. 意味変数" category: Manual permalink: /manuals/1.0/ja/06-semantic-variables.html --- From 76c3535e602194ed76b10b4c1f6d138c3932c782 Mon Sep 17 00:00:00 2001 From: Akihito Koriyama Date: Fri, 20 Mar 2026 00:54:56 +0900 Subject: [PATCH 16/16] Fix nitpicks from CodeRabbit review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FAQ: simplify 整理していくことができます → 整理できます Tutorial: use Japanese link labels for consistency --- manuals/1.0/ja/14-faq.md | 2 +- manuals/1.0/ja/tutorial.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/manuals/1.0/ja/14-faq.md b/manuals/1.0/ja/14-faq.md index 2d260c1..7718900 100644 --- a/manuals/1.0/ja/14-faq.md +++ b/manuals/1.0/ja/14-faq.md @@ -187,7 +187,7 @@ A. 手順依存=線形/条件で結果が排他的=分岐/独立処理の合 A. はい、可能です。UseCase層をBeで置き換えて、Controllerからは`becoming(new …Input)`を呼ぶことで実現できます。 -徐々に内在/超越へ整理していくことができますので、段階的な移行が可能です。 +徐々に内在/超越へ整理できますので、段階的な移行が可能です。 ### Q16. DBや外部APIはどこで使いますか? diff --git a/manuals/1.0/ja/tutorial.md b/manuals/1.0/ja/tutorial.md index 690427c..a30dbef 100644 --- a/manuals/1.0/ja/tutorial.md +++ b/manuals/1.0/ja/tutorial.md @@ -398,6 +398,6 @@ src/ ## 次のステップ -- [Semantic Variables](./06-semantic-variables.html) - 意味変数の詳細 -- [Metamorphosis](./05-metamorphosis.html) - 変容と分岐パターン -- [Reason Layer](./08-reason-layer.html) - 超越の理解 +- [意味変数](./06-semantic-variables.html) - 意味変数の詳細 +- [変容](./05-metamorphosis.html) - 変容と分岐パターン +- [存在理由層](./08-reason-layer.html) - 超越の理解