# 実装戦略 - メソッド後置例外処理 ## 段階的実装ロードマップ ### Phase 15.6: 段階的意思決定モデル(基盤確立) #### 目標 メソッドレベルでの段階的意思決定を可能にする catch/cleanup 構文を追加 #### 核心概念:三段階意思決定 1. **Stage 1**: 通常処理(メソッド本体) 2. **Stage 2**: エラー処理(catch ブロック) 3. **Stage 3**: 最終調整(cleanup ブロック) #### 構文設計 ```nyash box StageDecisionBox { // ✅ 既存構文(互換維持) method traditional(arg) { return computation(arg) } // 🆕 段階的意思決定構文(安全モード) method safeStaged(arg) { return riskyOperation(arg) } catch (e) { me.logError(e) return defaultValue } cleanup { // リソース管理のみ(return禁止) me.releaseResources() } // 🔥 段階的意思決定構文(表現モード) method expressiveStaged(arg) { return complexOperation(arg) } catch (e) { me.logError(e) return errorValue } cleanup returns { // 最終判断も可能(return許可) me.releaseResources() if me.detectSecurityThreat(arg) { return "SECURITY_BLOCKED" } } } ``` #### 技術的実装 **パーサー拡張**: ```rust // src/parser/statements.rs に追加 fn parse_method_definition(&mut self) -> Result { // 既存のメソッドパース let method = self.parse_traditional_method()?; // 後置修飾子のチェック if self.current_token_is("catch") || self.current_token_is("cleanup") { let postfix = self.parse_method_postfix_modifiers()?; return Ok(ASTNode::MethodWithStaging { method, postfix }); } Ok(method) } fn parse_method_postfix_modifiers(&mut self) -> Result { let mut catch_clause = None; let mut cleanup_clause = None; if self.consume_if("catch") { catch_clause = Some(self.parse_catch_clause()?); } if self.consume_if("cleanup") { // cleanup returns の検出 let allow_returns = self.consume_if("returns"); cleanup_clause = Some(self.parse_cleanup_clause(allow_returns)?); } Ok(StagingModifiers { catch_clause, cleanup_clause }) } fn parse_cleanup_clause(&mut self, allow_returns: bool) -> Result { let body = self.parse_block()?; // 安全性チェック:cleanup(returnsなし)では return/throw を禁止 if !allow_returns { self.validate_cleanup_safety(&body)?; } Ok(CleanupClause { body, allow_returns, }) } fn validate_cleanup_safety(&self, block: &Block) -> Result<(), ParseError> { for stmt in &block.statements { match stmt { ASTNode::Return(_) => { return Err(ParseError::CleanupCannotReturn { hint: "Use 'cleanup returns' if intentional final decision is needed" }); } ASTNode::Throw(_) => { return Err(ParseError::CleanupCannotThrow { hint: "cleanup blocks are for resource management only" }); } _ => {} } } Ok(()) } ``` **AST変換**: ```rust // メソッド後置をTryCatchに正規化 impl ASTNode { fn normalize_method_postfix(method: Method, postfix: PostfixModifiers) -> Method { Method { name: method.name, params: method.params, body: vec![ASTNode::TryCatch { try_body: method.body, catch_clauses: postfix.catch_clause.into_iter().collect(), finally_clause: postfix.finally_clause, }], return_type: method.return_type, } } } ``` **Bridge互換性**: - 既存のResult-mode lowering完全再利用 - ThrowCtx機構そのまま活用 - PHI-off (edge-copy) 合流維持 #### 仕様の明確化(Phase 15.6) EBNF(段階的意思決定構文) ``` methodDecl := 'method' IDENT '(' params? ')' block stagingModifiers? stagingModifiers := catchClause? cleanupClause? catchClause := 'catch' '(' (IDENT IDENT | IDENT | ε) ')' block cleanupClause := 'cleanup' cleanupMode block cleanupMode := 'returns' (* 表現モード:return/throw許可 *) | ε (* 安全モード:return/throw禁止 *) ``` ゲート/フラグ - `NYASH_STAGING_DECISION=1`(または `NYASH_PARSER_STAGE3=1` と同梱) - `NYASH_CLEANUP_SAFETY_MODE=strict|permissive` (デフォルト: strict) 段階実行順序(時系列的意思決定) 1. **Stage 1**: メソッド本体実行 2. **Stage 2**: 例外発生時は catch ブロック実行 3. **Stage 3**: 常に cleanup ブロック実行(安全モードまたは表現モード) 優先順位(段階的エスカレーション) - メソッド本体内のブロック後置catchが存在する場合、そちらが優先(最も近い境界が先) - 次にメソッドレベルcatch、最後に呼出し側(外側)のcatchへ伝播 - cleanup は常に最終段階で実行(例外の有無に関わらず) スコープ/束縛 - `catch (e)` の `e` はcatchブロック内ローカル。メソッド本体スコープには漏れない - cleanup ブロックはメソッド本体の変数スコープにアクセス可能 cleanup 実行順序と安全性 - **安全モード** (`cleanup`): return/throw禁止、純粋リソース管理のみ - **表現モード** (`cleanup returns`): 最終判断可能、return/throwで段階3の意思決定 - cleanup 内の `return` は最終的な戻り値となる(Stage 3 の決定権) オーバーライド/署名 - メソッドレベルcatch/cleanup はシグネチャに影響しない(戻り値型/引数は従来通り) - cleanup returns の場合は事実上の意思決定権を持つが、型システム上は透明 - 将来: 段階効果ビット(staged effects)を導入し、継承階層での安全性を静的検査 エラー規約 - 複数catchはMVPでは非対応(構文受理する場合でも最初のみ使用) - 順序は `catch` → `cleanup` のみ許可。逆順・重複は構文エラー - `cleanup` と `cleanup returns` の混在は禁止(一意性の保証) #### 実装コスト - **パーサー**: 約100行追加 - **AST**: 約50行追加 - **Lowering**: 0行(既存再利用) - **テスト**: 約200行 #### 期待効果 - メソッド呼び出し側のtry-catch不要 - リソース管理の自動化 - エラー処理の統一化 ### Phase 16.1: メソッド後置定義(革新的構文) #### 目標 メソッドの処理内容を先に書き、署名を後置する構文 #### 構文 ```nyash box ModernBox { // 🚀 後置メソッド定義 { local result = heavyComputation(arg) return optimize(result) } method process(arg): ResultBox { return me.field1 + me.field2 } method getSum(): IntegerBox catch (e) { return 0 } } ``` #### 技術的実装 **パーサー拡張**: ```rust fn parse_box_member(&mut self) -> Result { if self.current_token_is("{") { // ブロックから開始 = 後置定義の可能性 let block = self.parse_block()?; if self.current_token_is("method") { let method_sig = self.parse_method_signature()?; let postfix = self.parse_optional_postfix()?; return Ok(ASTNode::PostfixMethod { body: block, signature: method_sig, postfix, }); } // 他の後置修飾子もチェック return self.parse_other_postfix_constructs(block); } // 従来構文 self.parse_traditional_member() } ``` EBNF(ブロック先行・メソッド後置) ``` postfixMethod := block 'method' IDENT '(' params? ')' ( 'catch' '(' (IDENT IDENT | IDENT | ε) ')' block )? ( 'finally' block )? ``` 先読み/二段化方針 - `}` 後のトークンを先読みして `method|as|catch|finally` を判定。`method` の場合は署名を読み、既に取得した block を try_body として束ねる。 - ブロック内で参照する引数名は「前方宣言」扱いとし、パーサ内部で仮束縛テーブルを用意して解決する(実装は二段正規化で可)。 #### 実装コスト - **パーサー**: 約150行追加 - **AST正規化**: 約100行 - **ドキュメント**: 大幅更新 #### 期待効果 - 思考の自然な流れ(処理→署名) - 複雑なメソッドの可読性向上 - コードレビューの効率化 ### Phase 16.2: 究極統一構文(哲学的完成) #### 目標 Everything is Block + Modifierの完全実現 #### 構文 ```nyash box UnifiedBox { // 🔥 Everything is Block + Modifier { return "Hello " + me.name } as field greeting: StringBox { return me.items.count() } as property size: IntegerBox { return complexCalculation(arg) } as method compute(arg): ResultBox catch (e) { return ErrorResult(e) } { return asyncOperation() } as async method fetch(): FutureBox finally { me.closeConnections() } } ``` #### 技術的実装 **統一パーサー**: ```rust enum BlockModifier { AsField { name: String, type_hint: Option }, AsProperty { name: String, type_hint: Option }, AsMethod { name: String, params: Vec, return_type: Option, is_async: bool, }, WithCatch { param: Option, body: Block }, WithFinally { body: Block }, } fn parse_block_with_modifiers(&mut self) -> Result { let block = self.parse_block()?; let mut modifiers = Vec::new(); while let Some(modifier) = self.parse_optional_modifier()? { modifiers.push(modifier); } Ok(ASTNode::BlockWithModifiers { block, modifiers }) } ``` **意味解析**: ```rust impl BlockWithModifiers { fn into_traditional_ast(self) -> Result { match self.modifiers.primary_modifier() { BlockModifier::AsField { .. } => self.to_field(), BlockModifier::AsMethod { .. } => self.to_method(), BlockModifier::AsProperty { .. } => self.to_property(), } } } ``` #### 実装コスト - **パーサー**: 約300行(大幅改造) - **意味解析**: 約200行 - **エラーメッセージ**: 約100行 - **移行ツール**: 約500行 #### 期待効果 - データと振る舞いの完全統一 - コンパイラ最適化の新機会 - 言語学習コストの削減 ## 互換性戦略 ### 後方互換性の確保 ```nyash box MixedBox { // ✅ 従来構文(永続サポート) field oldField: StringBox method oldMethod() { return traditional() } // ✅ 新構文(段階的導入) { return computed() } as field newField: StringBox method newMethod() { return modern() } catch (e) { return fallback() } } ``` ### 移行支援ツール ```bash # 自動変換ツール nyash-migrate --from traditional --to postfix src/ # 段階的移行 nyash-migrate --phase 15.6 src/ # メソッドレベルcatch/finally nyash-migrate --phase 16.1 src/ # 後置定義 nyash-migrate --phase 16.2 src/ # 統一構文 ``` ## 性能への影響 ### 実行時性能 - **変化なし**: AST正規化により従来と同じMIR生成 - **最適化機会**: 統一構文による新しい最適化パス ### コンパイル時間 - **Phase 15.6**: 影響なし(既存パス再利用) - **Phase 16.1**: +5-10%(パーサー複雑化) - **Phase 16.2**: +10-15%(意味解析追加) ### メモリ使用量 - **AST**: +10-15%(中間表現の追加) - **実行時**: 変化なし(同じMIR生成) ## テスト戦略 ### 段階的テスト ```bash # Phase 15.6 テスト ./test/method-postfix-catch/ ├── basic-catch.nyash ├── basic-finally.nyash ├── catch-and-finally.nyash ├── nested-methods.nyash └── resource-management.nyash # Phase 16.1 テスト ./test/postfix-method-definition/ ├── simple-postfix.nyash ├── complex-signature.nyash ├── with-catch.nyash └── mixed-styles.nyash # Phase 16.2 テスト ./test/unified-syntax/ ├── field-method-property.nyash ├── async-methods.nyash ├── performance-comparison.nyash └── migration-compatibility.nyash ``` ### 回帰テストの確保 - 全既存テストがPhase 15.6で継続PASS - 新構文と旧構文の等価性検証 - パフォーマンス回帰の監視 ## リスク評価と対策 ### 技術的リスク 1. **パーサー複雑化** → 段階的実装で複雑性管理 2. **エラーメッセージ** → 専用のエラー報告機構 3. **IDE対応** → Language Server Protocol拡張 ### 採用リスク 1. **学習コスト** → 段階的導入と豊富なドキュメント 2. **コミュニティ分裂** → 互換性維持と移行支援 3. **ツール対応** → 既存ツールとの互換性確保 ### 対策 - **保守的ロールアウト**: 各フェーズで十分な検証期間 - **フィードバック収集**: ベータユーザーからの積極的意見収集 - **フォールバック計画**: 問題発生時の迅速な巻き戻し手順 ## 成功指標 ### 技術指標 - [ ] 全既存テストがPASS(100%) - [ ] 新構文テストカバレッジ(95%+) - [ ] パフォーマンス劣化なし(±3%以内) - [ ] コンパイル時間増加最小(+15%以下) ### 利用指標 - [ ] メソッドレベル例外処理の採用率(50%+) - [ ] 後置定義構文の採用率(30%+) - [ ] 統一構文の採用率(20%+) - [ ] 開発者満足度向上(Survey) ### 影響指標 - [ ] 例外関連バグの削減(30%+) - [ ] コードレビュー時間短縮(20%+) - [ ] 新規開発者の学習時間短縮(25%+) - [ ] 他言語からの影響検証(学術追跡) --- **最終更新**: 2025年9月18日 **実装責任者**: ChatGPT (基盤実装) + 段階的拡張チーム **状態**: Phase 15.6実装準備完了、Phase 16.x設計完了